Skip to content

X86 calling conventions

x86 아키텍처에 쓰이는 호출 규약에 대해 기술한다.

stdcall vs cdecl

__stdcall__cdecl의 간략한 차이점에 대하여 정리한다.

  • cdecl은 호출한 함수가 Stack을 정리한다.
  • stdcall은 호출된 함수 내부에서 Stack을 정리한다.
    • SP(Stack Pointer)를 ADD로 정리하는 방식 보다 asm:ret를 사용하는 방식이 더 빠르다.
  • stdcall 방식은 cdecl방식보다 빠르지만 가변 인자를 지원하지 못한다.
    • 가변인자는 함수 내부에서 인자의 개수를 단편적으로 확인할 수 없기 때문이다.
  • OS가 호출하는 함수나 DLL에 들어가는 함수는 가능하면 stdcall을 쓴다.

cdecl

__cdecl은 C 및 C++ 프로그램의 기본 호출 규칙입니다. 스택은 호출자에 의해 정리되기 때문에 vararg 함수를 수행할 수 있습니다. __cdecl 호출 규칙은 각 함수 호출에 스택 정리 코드를 포함시키기 때문에 __stdcall보다 큰 실행 가능 명령문을 생성합니다. 다음 목록에서는 이러한 호출 규칙의 구현을 보여 줍니다.

요소

구현

인수 전달 순서

오른쪽에서 왼쪽

인수 전달 규칙

호출하는 함수가 스택에서 인수를 꺼냅니다.

스택 유지 관리 책임

호출된 함수가 스택에서 자신의 인수를 꺼냅니다.

이름 데코레이션 규칙

밑줄 문자(_)는 C 링크를 사용하는 __cdecl 함수를 내보내는 경우를 제외하고 이름 앞에 붙습니다.

대/소문자 변환 규칙

대/소문자 변환은 수행되지 않습니다.

stdcall

__stdcall 호출 규칙은 Win32 API 함수를 호출하는 데 사용됩니다. 호출 수신자가 스택을 정리하므로 컴파일러는 vararg 함수를 __cdecl로 만듭니다. 이 호출 규칙을 사용하는 함수에는 함수 프로토타입이 필요합니다.

요소

구현

인수 전달 순서

오른쪽에서 왼쪽

인수 전달 규칙

포인터 또는 참조 형식이 전달되지 않는 경우 값으로 전달

스택 유지 관리 책임

호출된 함수가 스택에서 자신의 인수를 꺼냅니다.

이름 데코레이션 규칙

밑줄(_)이 이름 앞에 붙습니다. 이름 뒤에는 기호(@)가 오고 그 위에 인수 목록의 바이트 수(10진수)가 옵니다.
따라서 int func( int a, double b )로 선언된 함수는 _func@12로 데코레이팅됩니다.

대/소문자 변환 규칙

없음

fastcall

__fastcall 호출 규칙은 가능하면 함수의 인수가 레지스터로 전달되도록 지정합니다. 이 호출 규칙은 x86 아키텍처에만 적용됩니다. 다음 목록에서는 이러한 호출 규칙의 구현을 보여 줍니다.

요소

구현

인수 전달 순서

왼쪽에서 오른쪽으로 인수 목록에서 발견된 처음 두 개의 DWORD 이하 인수는 ECX 및 EDX 레지스터로 전달되고, 다른 모든 인수는 오른쪽에서 왼쪽으로 스택에 전달됩니다.

스택 유지 관리 책임

호출된 함수가 스택에서 인수를 꺼냅니다.

이름 데코레이션 규칙

이름 앞에 at 기호(@)가 붙습니다. 이름 뒤에는 at 기호 다음에 매개 변수 목록의 바이트 수(10진수)가 붙습니다.

대/소문자 변환 규칙

대/소문자 변환은 수행되지 않습니다.

See also

Favorite site

References


  1. Egloos.zum.com-qufl1999-stdcall_vs_cdecl.pdf 

  2. C_and_Cpp_calling_convention_-_cdecl_vs_pascal_vs_stdcall.pdf