▣ Calling Convention ?
호출자(caller, 피호출자 함수를 호출하는 함수)
피호출자(callee, 호출자로부터 호출되는 함수) 간에 미리 정해둔
파라미터의 전달 순서와 사용이 끝난 후의 스택 정리에 대한 규약
WIN32 환경에서는 기본적으로 세 가지의 호출 방식이 존재한다.
Caller Clearing 호출자가 정리
MyFunction, 1, 2, 3, 4
PUSH 4
PUSH 3
PUSH 2
PUSH 1
CALL MyFunction
ADD sp, 16 ; 스택 정리 코드
- 장점 : 호출하는 측에서 스택에다 몇 개의 파라미터를 집어넣었는지 알고, 스택 정리를 담당하므로, 가변 인자(variable arguments)를 사용할 수 있다.
- 단점 : 프로그램의 크기가 커진다. 호출자가 스택을 정리한다는 말은, 위에서도 보듯이 함수 호출할 때마다 스택 정리하는 코드가 들어가야 한다는 말이고, 이는 프로그램의 크기 증가와 속도 감소를 가져온다.
- printf 함수 같은 것이 가변 인자를 사용하는 대표적인 예이다. 하지만 피호출자는 인자가 몇개나 전달되었는지 정확히 알 수 없다. 그냥 포맷 문자열 같은 것을 이용해서 추측할 뿐이다. 예를 들어 printf 함수를 호출할 때, "%i %i %i" 문자열을 주면, printf 함수는 호출하는 측에서 추가적으로 스택에다 3개의 인자를 집어넣지 않은 경우(프로그래머의 실수!)에도, 스택에 있는 3개의 값을 이용해 문자열을 생성할 것이다. 이것이 크래시를 일으킬지, 아닐지는 정확히 알 수 없다. 3개 이상의 인수를 전달하는 경우는 어차피 호출하는 측에서 스택을 정리하므로 문제가 되지 않는다.
Callee Clearing 피호출자가 정리
MyFunction, 1, 2, 3, 4
PUSH 4
PUSH 3
PUSH 2
PUSH 1
CALL MyFunction
- 장점 : 피호출자가 스택 정리를 담당한다면, 프로그램의 크기는 작아진다. 또한 스택 정리 명령어를 매번 호출하지 않아도 되므로, 속도 또한 빨라진다.
- 단점 : 피호출자가 자신이 정리할 스택의 크기(파라미터들의 총 크기)를 정확히 알고 있어야 하므로, 가변 인자를 사용할 수 없다.
- 호출자가 하든, 피호출자가 하든 어딘가에서는 스택을 정리해야하지 않는가? 즉 위에서 없어진 ADD sp, 16는 어차피 피호출자, 즉 MyFunction 내부에서 호출해야 하지 않느냐는 말이다. 어차피 어디에선가 호출해야 한다면 프로그램의 크기가 왜 작아지며, 빨라지는가? 이는 인텔 계열에서 지원하는 특수한 명령어 때문이다. 즉 리턴하면서 스택 정리를 동시에 하는 명령어가 있기 때문에, 프로그램의 크기가 작아지고, 빨라진다는 말이다.
Calling Conventions |
매개변수 전달방향 |
Stack Clearing | Name Decorations | Notes |
---|---|---|---|---|
__cdecl | Right → Left | Callee 피호출자 | 함수 이름 앞에 _를 붙인다. Ex) _foo | C/C++함수의 기본 호출 규약 |
__stdcall | Right → Left | Caller 호출자 | _가앞에 붙고 뒤에 @와 인자의 크기가 10진수로 붙는다. Ex) _foo@12 | 대부분의 System 함수가 사용. VB에서 내부함수가 사용. |
__fastcall | 첫번째 2개의 DWORD 파라미터는 ECX, EDX 레지스터 사용. 나머지는 Right→Left | Callee 피호출자 | @이 앞에 붙고 @과 인자의 크기가 10진수로 뒤에 붙는다. Ex) @foo@12 | Intel CPU 만 사용. Borland의 Delphi 컴파일러가 사용. |
this | Right → Left this 매개변수는 ECX 레지스터사용. | 호출자가 Stack에서 인자를 제거한다. | None | C++클래스의 멤버 함수가 사용. COM에서 사용. |
naked | Right → Left | 호출자가 Stack에서 인자를 제거한다. | None | VxD에서 사용. Custom Prolog 와 Epilog를 만들때 사용. |
출처 : http://serious-code.net/moin.cgi/CallingConvention
참고 : http://kkamagui.springnote.com/pages/339546
'OLD_posting' 카테고리의 다른 글
PE (Portable Executable) 포맷 (0) | 2010.11.24 |
---|---|
Caller/Callee Seaved Register (0) | 2010.11.15 |
ALU (arithmetic-logic unit) - 산술논리 연산장치 (0) | 2010.11.15 |
끄적끄적.. (0) | 2010.01.09 |
Big & Little Endian (0) | 2010.01.09 |