티스토리 뷰
함수 호출 규칙calling convention은 호출자 함수가 피호출자 함수를 호출하는 과정에서 매개변수를 전달하는 순서 및 매개변수가 사용한 메모리 관리방법 등에 관한 규칙입니다.
대표적으로 __cdecl, __stdcall, __fastcall 등 세 가지 정도가 있는데 이 세가지가 C언어의 표준에서 정의하는 것은 아닙니다.
세 가지 모두 약간씩 차이가 있는데 C/C++ 컴파일러의 기본 함수 호출 규칙은 __cdecl입니다.
호출 규칙 | 매개변수 스택 정리 | 매개변수 메모리 |
__cdecl | Caller | Stack |
__stdcall | Callee | Stack |
__fastcall | Callee | Stack + Register |
17.2.1 __cdecl
__cdecl 호출 규칙은 매개변수를 오른쪽부터 스택에 Push합니다.
또한, __cdecl 호출 규칙은 매개변수로 인해 증가한 스택을 호출자 함수가 본래 크기로 줄입니다.
#include<stdio.h>
int __cdecl GetMax(int a, int b, int c)
{
int nMax = a;
if(b > nMax) nMax = b;
if(c > nMax) nMax = c;
return nMax;
}
int __cdecl main(void)
{
int nRes = 0;
nRes = GetMax(1, 2, 3);
return 0;
}
오른쪽 3부터 스택에 Push하는 것을 내부를 살펴보면 확인할 수 있습니다.
main() 함수 내부에서는 add esp, 0Ch 라는 연산을 수행합니다.
여기서 '0Ch'는 0x0C 즉, 10진수 12를 의미하며, esp(extended stack pointer)는 스택 메모리에 대한 '포인터'입니다. 포인터이므로 당연히 주소가 들ㅇ 있는데, 이주소에 대해 ADD 연산을 수행하면 당연히 주소는 증가합니다.
그러니까, 지금 코드에서는 12바이트만큼 증가합니다. 주소가 증가했다는 것은 스택의 감소를 의미합니다. 즉, main() 함수에 들어가는, 이 한줄의 코드로 스택은 GetMax() 함수호출 전 상태로 복원되는 것입니다.
이것 때문에 자동변수 매모리가 자동으로 관리된다고 말하는 것입니다.
17.2.2 __stdcall
매개변수를 오른쪽부터 스택에 Push하는 것은 같습니다.
그러나, 매개변수로 인해 증가한 스택을 호출자 함수가 정리하는 것이 아니라 피호출자 함수가 정리합니다.
__cdecl 호출 규칙에서 본 add esp, 0Ch 연산은 존재하지 않습니다.
GetMax() 함수를 호출한 이후로 mov dword ptr [nRes], eax라는 연산이 수행되었는데, 이는 GetMax() 함수가 반환한 값을 nRes에 대입하는 C 코드에 대한 어셈블리 코드입니다.
17.2.3 __fastcall
__fastcall은 __stdcall처럼 매개변수는 오른쪽부터 스택에 Push하고 피호출자 함수가 스택을 정리합니다.
단, 매개변수가 여러 개면 가장 나중에 Push되어야 할 왼쪽 첫 번째, 두 번째 매개변수는 스택 대신 CPU의 레지스터(EDX, ECX)를 이용해 전달합니다.
'언어 > C' 카테고리의 다른 글
함수 포인터와 역호출 구조 - 독하게 시작하는 C프로그래밍 (0) | 2019.11.03 |
---|---|
매크로 - 독하게 시작하는 C프로그래밍 (0) | 2019.10.31 |
형한정어, 외부변수 선언, 형 재선언, 열거형 상수 - 독하게 시작하는 C프로그래밍 (0) | 2019.10.24 |
파일 시스템 기본 이론 - 독하게 시작하는 C프로그래밍 (0) | 2019.10.23 |
비트필드, 공용체 - 독하게 시작하는 C프로그래밍 (0) | 2019.10.04 |
- Total
- Today
- Yesterday
- Algorithm
- 공부
- 포인터
- 1차원 배열
- call by value
- 강의
- 자료구조
- 다차원 배열
- 2차원 배열
- 형승격
- 직접 지정
- 간접 지정
- 비트필드
- 3차원 배열
- 알고리즘
- 재귀함수
- C
- 공용체
- 배열
- timecomplexity
- inflearn
- 시간복잡도
- 회전리스트
- 종류
- 공간복잡도
- 구조체
- 파이썬
- call by reference
- 프로그래밍
- codeit
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |