제임스딘딘의
Tech & Life

개발자의 기록 노트/C++ MFC

Function Calling Conventions

제임스-딘딘 2011. 12. 17. 05:22


함수 호출 규약(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와의 이식성이 없기때문에 일반 응용프로그램에서는 거의 사용되지 않는다. 주로 디바이스 드라이버를 만들 때 사용한다.