함수 호출시 매개변수를 전달하는 방식과 스택 프레임을 반환하는 방식을 약속해 놓은것을 가리켜 함수 호출규약이라고 부른다
#define CALLBACK __stdcall
#define WINAPI __stdcall
#define APIENTRY __stdcall
int __stdcall STDCallFunction(int a, int b);
int APIENTRY wWinMain(//);- Windows 시스템 함수 선언에서는 매크로를 사용하여
__stdcall을 표현한다. - 함수 호출규약을 명시하지 않은 함수들은 디폴트 선언을 따르게 된다.(그동안 계속 사용하던 방식)
__cdecl
- C/C++의 디폴트 호출규약
- 오른쪽에 있는 매개변수가 먼저 스택에 쌓이는 C스타일 방식
- Caller가 스택 프레임을 정리
//Caller(main함수)에서 스택 정리
int Func(int a, int b)
{
return a+b;
}
int main()
{
Func(1,2);
return 0;
}**호출 순서1
- 매개 변수를 스택에 저장(2, 1 순서)
- Func 함수를 호출(이동)
- Func에서 [스택 포인터]를 이용하여 스택에 저장된 데이터 사용
- return 이후 main함수로 복귀
- main함수에서 SP를 Func 호출로 줄어든 만큼 다시 증가(스택 프레임 정리)
__stdcall
- 호출된 함수 내에서 스택 프레임을 반환
- Win32API에서 사용하는 CallBack 함수에서 자주 사용됨
//Callee(Func함수)에서 스택 정리
int Func(int a, int b)
{
return a+b;
}
int main()
{
Func(1,2);
return 0;
}**호출 순서
- cdecl과 동일
- return 부분에서 SP정리 시 Func에서 정리
__fastcall
- cdecl과 매우 유사하지만 전달할 매개 변수의 개수에 따라 스택의 사용 여부 결정
- 매개 변수가 2개 이하일 경우 ECX, EDX 라는 레지스터에 저장하는 방식으로 인자를 전달(접근, 연산속도 up)2
- 매개 변수가 2개를 넘을 경우 cdcel 방식과 마찬가지로 3번째 매개 변수 부터 스택을 사용
cdecl과 stdcall
- 어셈블리 수준에서 두 방식을 비교했을 때 stdcall은 코드 한줄로 return과 스택 정리가 가능 하지만, cdecl 방식은 return 후 스택을 정리하는 코드가 더 필요하다3
- printf 같은 가변인자 함수는 Caller가 스택을 정리하는 cdecl방식을 사용해야만 한다4