Calling Convention
Calling Convention?
Calling Convention
은 함수 호출 시에 어떻게 매개변수를 전달하고, 함수의 결과를 반환하는지에 대한 규칙들의 집합을 나타냅니다. Calling Convention은 아래와 같은 것들을 다루고 있습니다.
- 매개변수 전달 방법(Parameter Passing): 함수에 전달되는 매개변수는 레지스터, 스택, 또는 혼합된 방법으로 전달될 수 있습니다.
- 스택 사용(Stack Usage): 함수 호출 및 반환 중에 스택이 어떻게 사용되는지에 대한 규칙을 정의합니다.
- 레지스터 사용(Register Usage): 어떤 레지스터가 함수 호출에서 어떻게 사용되는지를 정의합니다. 몇몇 Calling Convention은 특정 레지스터를 특별한 목적으로 예약하기도 합니다.
- 반환 값(Return Value): 함수의 반환 값이 어디에 저장되는지, 그리고 반환 값을 어떻게 전달하는지에 대한 규칙을 명시합니다.
- 스택 프레임(Stack Frame): 로컬 변수, 매개변수, 반환 주소 등이 어떻게 스택에 배치되는지에 대한 규칙을 정의합니다.
Calling Convention에는 대표적으로 cdecl, stdcall, fastcall가 있으며 보통 컴파일러가 자동으로 관리하게 됩니다.
💡 cdecl, stdcall, fastcall Calling Convention은 32bit에서 주로 사용하는 것들이고, 64bit에서는 fastcall 방식만 사용합니다!
cdecl(C Declaration)
c언어에서 주로 사용합니다. 프로그래밍할 때 흔히 사용하는 함수들이 해당 규약에 속합니다.
- 매개변수 전달: 호출자(caller)가 스택에 매개변수를 순서대로 push하며, 호출된 함수(callee)는 스택을 통해 매개변수에 접근합니다. 호출자가 스택을 정리합니다.
- 스택 사용: 호출자가 스택을 정리합니다.
- 레지스터 사용: 특별한 레지스터 규약이 없습니다.
1
2
3
int add(int a, int b) {
return a + b;
}
stdcall (Standard Call):
- 매개변수 전달: 호출자가 스택에 매개변수를 push하며, 호출된 함수가 스택을 정리합니다. 함수의 이름 뒤에
@n
이 붙는데,n
은 전달된 매개변수의 크기를 나타냅니다. - 스택 사용: 호출된 함수가 스택을 정리합니다.
- 레지스터 사용: 특별한 레지스터 규약이 없습니다.
1
2
3
int __stdcall add(int a, int b) {
return a + b;
}
fastcall (Fast Call)
- 매개변수 전달: 레지스터를 사용하여 최대한의 매개변수를 전달합니다. 보통 처음 몇 개의 매개변수는 레지스터에 할당되고, 나머지는 스택을 통해 전달됩니다.
- 스택 사용: 나머지 매개변수 및 일부 기타 데이터는 스택을 통해 전달됩니다.
- 레지스터 사용: 레지스터를 효과적으로 활용합니다.
1
2
3
int __fastcall add(int a, int b) {
return a + b;
}
64bit 기준으로 레지스터는 rdi, rsi, rdx, rcx, r8, r9를 통해 순서대로 넘겨지게된다.
This post is licensed under CC BY 4.0 by the author.