728x90

함수 호출규약 : 함수 호출시 인자를 전달하는 방식과 스택 프레임을 반환하는 방식

 

_cdecl, _stdcall + &

함수 선언부에 주로 존재하는 _stdcall 이라는 키워드는 함수 호출규약을 지정하는 것이다. _stdcall 호출 규약에 따라서 STDCallFunction함수의 호출과 반환을 처리하라는 뜻이다.

ex) int __stdcall STDCallFunction(int a, int b, int c);

 

WINAPI, APIENTRY, CALLBACK 등의 키워드는 아래와 같이 정의되어 있는 매크로이다.

#define CALLBACK  __stdcall

#define WINAPI  __stdcall

 

Windows 시스템 함수 선언에서는 키워드 __stdcall를 직접 사용하지 않는다. CALLBACK이나 WINAPI라는 또다른 이름을 부여해서 그 함수의 특성 파악에 도움을 주도록 하고있다.

 

ex)int CALLBACK EventRoutine(void);

CALLBACK은 실제로 __stdcall로 정의되어 있으므로, EventRoutine이라는 함수는 __stdcall호출 규약을 따를 것이다. 또한 콜백(CallBack)함수임을 파악할 수 있다. 함수 호출 규약이 선언되어 있지 않은 함수들은 디폴트 속성으로 선언된다.

 

콜백(CallBack)함수란, Windows 시스템에 의해 자동으로 호출되는 함수를 의미한다. 특정 상황에서 호출되어야 할 함수를 등록시키는 것이 가능한데, 이때 등록이 되는 함수를 가리켜 콜백 함수라 한다.

 

 

Calling Conventions

Segment

Word Size

Calling

Convention

Parameters

in rgisters

Parameter order on stack

Stack

Cleanup by

32bit

__cdecl

 

C

Caller

__stdcall

 

C

Function

__fastcall

ecx,edx

C

Function

__thiscall

ecx

C


Function

64bit

windows

(MS, Intel)

rcx/xmm0,

C

Caller

rdx/xmm1,

r8/xmm2,

r9/xmm3,

Linux, BSD

(GNU, Intel)

rdi, rsi,

C

Caller

rdx, rcx, r8

r9, xmm0-7

32비트 기반 함수 호출규약

__cdecl은 C/C++의 디폴트 호출규약이다. 인자 전달 방식은 C언어 스타일을 따르는데, C언어 스타일은 전달되는 인자가 스택에 쌓이는 방식을 의미한다. 반환 시에는 함수를 호출하는 호출자가 스택프레임을 반환한다.

__stdcall와 __cdecl의 차이점은 스택프레임을 반환하는 주체이다.

__stdcall은 호출된 함수 내에서 스택프레임을 반환하도록 정의되어 있다.

__cdecl은 호출자가 스택 프레임을 반환한다.

 

__fastcall은 말그대로 함수 호출을 빠르게 처리하기 위한 호출규약이다. __fastcall은 함수 전달인자를 두개까지 레지스터를 사용한다. 첫번쨰 전달인자는 ecx, 두번쨰 전달인자는 edx를 통해 저장된다. 두개가 넘어서면 스택을 사용한다. 이 호출규약에서 레지스터를 사용하는 것이 함수 호출이 빨라지는 근거가 된다.

 

64비트 기반 함수 호출 규약

Windows기반에서는 총 8개의 레지스터를 활용해서 전달되는 인자로 저장하게 되는데, 실제로 레지스터에 저장되는 전달인자 개수는 4개에 지나지 않는다. rcx/xmm0는 첫번째 전달인자가 rcx 혹은 xmm0레지스터에 저장된다는 것을 의미한다. 총 4개의 전달인자까지만 레지스터를 통해 처리한다.

Linux 또는 BSD에서는 최대 14개의 인자까지 레지스터를 통해 처리하는 경우도 있다.

728x90

+ Recent posts