CALLBACK = WINAPI = PASCAL = __stdcall위에서 알 수 있듯이, MS Windows의 calling convetion은 __stdcall과 __cdecl로 나뉜다.
WINAPIV = __cdecl
이렇게 calling convetion을 둘로 나눈 이유는 함수 호출 후, stack pointer (sp)를 누가 원래데로 돌려놓을지 (정리할지)를 분간하기 위함이다. 결론 부터 애기하자면, __stdcall을 이요하면, callee측에서 sp를 정리하고, __cdecl을 이용하면, caller측에서 sp를 정리한다.
예를 들어보자.
SimpleFunction(TYPE arg1, TYPE arg2, TYPE arg3) { … }__cdecl의 경우, assembly code는 대략 다음과 같이 구성된다.
SimpleFunction(…);
push arg3
push arg2
push arg1
call SimpleFunction
Add sp, 12
반면 __stdcall의 경우는 대락 다음과 같이 구성된다.
push arg3
push arg2
push arg1
call SimpleFunction
Assembly code를 보면 알 수 있듯이, __cdecl은 함수가 return된 이후에, caller가 직접 sp를 정리하고, __stdcall은 callee측에서 정리를 해주기 때문에, caller 쪽에서는 함수가 return된 이후에 sp 정리 작업을 하지 않는다.
sp의 정리를 어느 쪽에서 하든, 차이가 없어보이지만 두가지 정도 차이가 생길 수 있다.
먼저, 속도와 관련된 문제이다. 8086 계열의 assembly 명령어 중,
다음으로, 가변 arguments의 지원 여부이다. __cdecl을 이용하면, caller측에서 sp를 정리하기 때문에, 가변 arguments를 지원할 수 있다.
사실, 몇가지 차이점이 더 있는 듯 하지만, 지금까지 파악된 부분은 이 두가지이다.
No comments:
Post a Comment