함수 호출 규약(Function Calling Convention)에 대하여 정리해 보자.
일단 Microsoft의 Calling Convention의 종류는 다음과 같다
Calling Convention | Argument Passing | Stack Maintenance | Name Decoration (C only) | Notes |
__cdecl | Right to left. | Calling function pops arguments from the stack. | Underscore prefixed to function names. Ex: _Foo. | This is the default calling convention for C/C++ |
__stdcall | Right to left. | Called function pops its own arguments from the stack. | Underscore prefixed to function name, @ appended followed by the number of decimal bytes in the argument list. Ex: _Foo@10. | This is the almost system calling convention. |
__fastcall | First two DWORD arguments are passed in ECX and EDX, the rest are passed right to left. | Called function pops its own arguments from the stack. | A @ is prefixed to the name, @ appended followed by the number of decimal bytes in the argument list. Ex: @Foo@10. | Only applies to Intel CPUs. This is the default calling convention for Borland Delphi compilers. |
thiscall | this pointer put in ECX, arguments passed right to left. | Calling function pops arguments from the stack. | None. | Used automatically by C++ code. Used by Com |
naked | Right to left. | Calling function pops arguments from the stack. | None. | Used by VxDs. Used by Custom Prolog and Epilog |
1. __cdecl
- 인자 파싱 : Right -> Left
- 스택 관리 : Caller, 가변 인자 허용
- Name Mangling : 함수 이름 앞에 _추가
ex) _Foo - C와 C++ 함수의 기본 호출 규약
- 기본 호출 규약이므로 /Gz(stdcall) 또는 /Gr(fastcall) 옵션이 켜졌을 때, 필요한 변수나 함수 이름 앞에 __cdecl을 놓으면 된다.
/Gd 옵션은 강제로 _cdecl 규약으로 호출한다.
2. __stdcall
- 인자 파싱 : Right -> Left
- 스택 관리 : Calle
- Name Mangling : 함수 이름 앞에 _추가, 함수 이름 뒤에 @추가 되고 @뒤에 다시 매개변수의 전체바이트에 해당하는 10진수가 추가된다.
ex) _Foo@12 - 거의 모든 시스템 함수에서 사용되는 호출 규칙이다.( WinAPI )
- /Gz 옵션은 C++멤버 함수와 __cdecl 또는 __fastcall이 표시된 함수를 제외한 모든 함수에 __stdcall 호출 규칙을 지정한다. 모든 __stdcall함수는 프로토타입을 가져야 한다. 가변 인수를 취하는 함수는 __cdecl로 표시해야 한다.
3. __fastcall
- 인자 파싱 : 처음 2개의 DWORD 또는 더 작은 인자들은 ecx와 edx에 전달, 나머지 인자들은 Right-> Left
- 스택 관리 : Callee.
- Name Mangling : 함수 이름 앞과 끝에 @가 추가되고 @뒤에 매개변수의 전체바이트에 해당하는 10진수가 추가된다.
ex) @Foo@12 - /Gr 옵션은 선언된 함수가 충돌하지 않고 이름이 main이 아니라면, 모듈 내 각 함수를 fastcall로 컴파일 한다.
4. thiscall
- 인자 파싱 : Right -> Left, this 매개 변수가 ecx레지스터에 전달.
- 스택 관리 : Caller.
- Name Mangling : 없음.
- 가변인자를 허용하지 않는 C++멤버함수의 기본 호출 규약으로 스택 끝에 this포인터를 넣으며 컴파일시 컴파일러에 의해 가변인자 함수는 __cdecl로 변경된다. thiscall은 키워드가 아니므로 thiscall 호출 규약은 명시적으로 사용할 수 없다. 모든 매개 변수들은 스택상에 놓여진다.
5.naked
- 인자 파싱 : Right -> Left
- 스택 관리 : Caller
- Name Mangling : 없음
- stack frame이 생략.
- 컴파일러가 기본적으로 만들어주는 Prolog와 Epilog를 변경할 때 사용된다. naekd를 사용하게 되면 아래와 같은 Prolog와 Epilog를 컴파일러가 생성하지 않는다. 사용자가 stack frame을 할당하여 사용해야 된다. 이는 CPU와의 이식성이 없기때문에 일반 응용프로그램에서는 거의 사용되지 않는다. 주로 디바이스 드라이버를 만들 때 사용한다.
'개발자의 기록 노트 > C++ MFC' 카테고리의 다른 글
[STL] 어댑터 컨테이너 : queue 사용 예제 (0) | 2012.06.03 |
---|---|
[STL] Vector 사용 예제 (0) | 2012.06.03 |
[MFC] 공부중 (0) | 2012.06.02 |
구조체 패딩 비트에 대해서. struct padding bit (0) | 2011.08.20 |
[MFC] 알아두면 유용한 형변환 (0) | 2011.06.30 |
MFC 재배포 DLL (0) | 2011.06.16 |