X86 calling conventions
x86 아키텍처에 쓰이는 호출 규약에 대해 기술한다.
stdcall vs cdecl
- __stdcall 과 __cdecl 의 차이점!!!끝없는도전1<span style="color:red">(글의 상단에,
stdcall
과cdecl
의 정의가 바뀌었다)
__stdcall
과 __cdecl
의 간략한 차이점에 대하여 정리한다.
-
cdecl
은 호출한 함수가 Stack을 정리한다. -
stdcall
은 호출된 함수 내부에서 Stack을 정리한다.- SP(Stack Pointer)를 ADD로 정리하는 방식 보다 asm:ret를 사용하는 방식이 더 빠르다.
stdcall
방식은 cdecl
방식보다 빠르지만 가변 인자를 지원하지 못한다.- 가변인자는 함수 내부에서 인자의 개수를 단편적으로 확인할 수 없기 때문이다.
stdcall
을 쓴다. cdecl
__cdecl은 C 및 C++ 프로그램의 기본 호출 규칙입니다. 스택은 호출자에 의해 정리되기 때문에 vararg 함수를 수행할 수 있습니다. __cdecl 호출 규칙은 각 함수 호출에 스택 정리 코드를 포함시키기 때문에 __stdcall보다 큰 실행 가능 명령문을 생성합니다. 다음 목록에서는 이러한 호출 규칙의 구현을 보여 줍니다.
요소 | 구현 |
인수 전달 순서 | 오른쪽에서 왼쪽 |
인수 전달 규칙 | 호출하는 함수가 스택에서 인수를 꺼냅니다. |
스택 유지 관리 책임 | 호출된 함수가 스택에서 자신의 인수를 꺼냅니다. |
이름 데코레이션 규칙 | 밑줄 문자(_)는 C 링크를 사용하는 __cdecl 함수를 내보내는 경우를 제외하고 이름 앞에 붙습니다. |
대/소문자 변환 규칙 | 대/소문자 변환은 수행되지 않습니다. |
stdcall
__stdcall 호출 규칙은 Win32 API 함수를 호출하는 데 사용됩니다. 호출 수신자가 스택을 정리하므로 컴파일러는 vararg 함수를 __cdecl로 만듭니다. 이 호출 규칙을 사용하는 함수에는 함수 프로토타입이 필요합니다.
요소 | 구현 |
인수 전달 순서 | 오른쪽에서 왼쪽 |
인수 전달 규칙 | 포인터 또는 참조 형식이 전달되지 않는 경우 값으로 전달 |
스택 유지 관리 책임 | 호출된 함수가 스택에서 자신의 인수를 꺼냅니다. |
이름 데코레이션 규칙 | 밑줄(_)이 이름 앞에 붙습니다. 이름 뒤에는 기호(@)가 오고 그 위에 인수 목록의 바이트 수(10진수)가 옵니다. |
대/소문자 변환 규칙 | 없음 |
fastcall
__fastcall 호출 규칙은 가능하면 함수의 인수가 레지스터로 전달되도록 지정합니다. 이 호출 규칙은 x86 아키텍처에만 적용됩니다. 다음 목록에서는 이러한 호출 규칙의 구현을 보여 줍니다.
요소 | 구현 |
인수 전달 순서 | 왼쪽에서 오른쪽으로 인수 목록에서 발견된 처음 두 개의 DWORD 이하 인수는 ECX 및 EDX 레지스터로 전달되고, 다른 모든 인수는 오른쪽에서 왼쪽으로 스택에 전달됩니다. |
스택 유지 관리 책임 | 호출된 함수가 스택에서 인수를 꺼냅니다. |
이름 데코레이션 규칙 | 이름 앞에 at 기호(@)가 붙습니다. 이름 뒤에는 at 기호 다음에 매개 변수 목록의 바이트 수(10진수)가 붙습니다. |
대/소문자 변환 규칙 | 대/소문자 변환은 수행되지 않습니다. |
See also
Favorite site
- Wikipedia (en) x86호출규약에 대한 설명
- Wikipedia (ko) x86호출규약에 대한 설명
- 호출규약(__cdecl,__stdcall,__fastcall,thiscall,naked)
- MSDN: 데코레이팅된 이름
- [추천] C/C++ 호출규약 : __cdecl, __pascal, __stdcall 의 차이점 2