Calling Convention
1 콜링컨벤션
스택을 이용하여 파라미터를 전달할 때 파라미터를 스택에 넣는 순서와 전달된 파라미터를 어느곳에서 해제할 것인지 등을 결정하는 방식
가) __cdecl
① C 또는 C++프로그램에서 파라미터 전달시 디폴트로 사용하는 방식으로 이 방식에 의한 파라미터 전달은 오른쪽에서 왼족 방향으로 이루어지게 되며 프로시저를 호출한 쪽에서 파라미터에 대한 해제를 책임진다.
main() { Sum(1, 2); } int Sum( int a, int b ) { return a+b; } |
Main: push 2 push 1 call sum add esp, 8 Sum: push ebp ( 이전 프로시저의 ebp값을 저장 ) mov ebp, esp( 이전 프로시저의 ebp값을, push한 시점의 esp를 현재 스택 프레임의 ebp로 설정) mov eax, dword ptr[ebp+0x8] add eax, dword ptr[ebp+0xc] pop ebp ret |
나) __stdcall
Windows API의 프로시저에서 사용하는 방식으로 파라미터 전달은 __cdecl방식과 같이 오른쪽에서 왼쪽방향으로 스택에 저장하게 되지만 파라미터의 해제는 프로시저가 복귀되기 전에 이루어 진다.
main() { Sum(1, 2); } int Sum( int a, int b ) { return a+b; } |
Main: push 2 push 1 call sum Sum: push ebp mov ebp, esp mov eax, dword ptr[ebp+0x8] add eax, dword ptr[ebp+0xc] pop ebp ret 8 |
① 장점
- 함수의 독립성이 뛰어남. 즉 프로시저를 부르기 전에 스택에 파라미터를 쌓아놓고 그 프로시저를 부르기만 하면 그 함수가 리턴되어진 후에는 그 프로시저의 스택포인터(esp)가 이전 상태로 복원되어 있으므로, 복귀된 후에 호출한 프로시저에 대하여 더 이상 신경을 쓰지 않아도 된다.
- 스택을 해제하는 코드가 호출한 프로시저 안에 있으므로 만약 이 프로시저가 여러곳에서 호출된다 하더라도 스택을 해제하는 코드는 프로시저 내에 하나만 존재하므로, 결국 __cdecl 방식에 비해 코드의 크기가 줄어든다.
다) __fastcall
① __fastcall 방식에서는 처음 두개의 파라미터는 스택을 이용하지않고 ecx와 edx 레지스터를 사용하며 그 이상의 파라미터에 대해서만 오른쪽에서 왼쪽 방향으로 스택에 저장하게 된다. 이 방식에서의 스택 제거는 __stdcall과 동일하다
라) 정리
Calling Convention |
파라미터 전달 |
스택메모리 제거 |
__cdecl |
오른쪽에서 왼쪽 방향으로 스택에 저장 |
호출한 쪽에서 처리 |
__stdcall |
오른쪽에서 왼쪽 방향으로 스택에 저장 |
호출 당한 쪽에서 처리 |
__fastcall |
처음 두개의 파라미터는 ecx와 edx 레지스터에 저장, 그 이상의 파라미터는 오른쪽에서 왼쪽 방향으로 스택에 저장 |
호출 당한 쪽에서 처리 |
'Windows Programming > 디버깅' 카테고리의 다른 글
VS2008 & VMWare7 원격디버깅 (0) | 2011.09.06 |
---|---|
Stack Frame구성 - Stack Overflow (0) | 2011.07.25 |
[디버깅을 위한 기초지식 #3] CallStack - 프로시저 호출에 따른 스택의 구성 (0) | 2011.07.18 |
[디버깅을 위한 기초지식 #2] 8086 명령어 (0) | 2011.07.18 |
[디버깅을 위한 기초지식 #1] CPU 레지스터의 종류와 용도 (2) | 2011.07.18 |