Post

Calling Convention

Calling Convention?

Calling Convention은 함수 호출 시에 어떻게 매개변수를 전달하고, 함수의 결과를 반환하는지에 대한 규칙들의 집합을 나타냅니다. Calling Convention은 아래와 같은 것들을 다루고 있습니다.

  1. 매개변수 전달 방법(Parameter Passing): 함수에 전달되는 매개변수는 레지스터, 스택, 또는 혼합된 방법으로 전달될 수 있습니다.
  2. 스택 사용(Stack Usage): 함수 호출 및 반환 중에 스택이 어떻게 사용되는지에 대한 규칙을 정의합니다.
  3. 레지스터 사용(Register Usage): 어떤 레지스터가 함수 호출에서 어떻게 사용되는지를 정의합니다. 몇몇 Calling Convention은 특정 레지스터를 특별한 목적으로 예약하기도 합니다.
  4. 반환 값(Return Value): 함수의 반환 값이 어디에 저장되는지, 그리고 반환 값을 어떻게 전달하는지에 대한 규칙을 명시합니다.
  5. 스택 프레임(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.