호출 규약

2021. 10. 25. 16:16CS 지식

호출 규약이란 함수를 호출하는 방식에 대한 약속이다.

즉 함수를 호출하는 곳과 호출 당하는 곳, 이 둘이 함수 처리를 동일하게 하기 위해서 만들어진 것이다.

이것은 혼자 프로그래밍할때는 크게 중요하지 않지만,

콜백함수를 쓰는등 외부 API / 라이브러리를 사용할 때 알아두어야 한다.

 

여러가지 호출 규약들이 있는데, 

이들은 인자 전달 방법(매체), 인자 전달 순서, Stack frame 정리 방법

에 따라 나뉜다.

 

인자 전달 방법은 함수를 호출할 때 어떤 공간으로 인자를 넘길 것인지를 말한다.

stack 메모리에 저장하여 넘길 수도 있고, 레지스터 메모리에 넣어 전달하는 방법도 있다.

 

인자 전달 순서는 말 그대로 오른쪽에 있는 인자부터 전달할건지 왼쪽에 있는 인자부터 전달할건지를 말한다.

대부분 RTL (Right To Left) 방식이다.

 

stack frame 정리 방법은,

함수가 종료되었을 때 인자가 있는 공간을 호출자(Caller)와 피호출자(Callee) 중

누가 이 공간을 정리할지를 결정하는 것이다. 각각의 메커니즘은..

호출자가 정리할 경우: 호출한 함수가 종료된 후, 연산으로 esp를 내려준다.

피호출자가 정리할 경우: 반환시 (어셈블리 ret명령) 크기를 인자로 넣어 esp를 내려준다.

또한 호출자가 stack frame을 정리할 경우에만 함수에 가변 인자를 사용할 수 있다.

 

아래는 대표적인 호출 규약이다.

x86 아키텍쳐의 대부분 C컴파일러는 cdecl 호출 규약을 사용하고 있다.

호출 규약 인자 전달 매체 인자 전달 순서 Stack frame 정리 주체
cdecl stack <- Caller
stdcall stack <- Callee
fastcall register(2개까지) + stack <- Callee

 

비쥬얼 스튜디오에서 속성 - C/C++ - 고급 - 호출 규칙으로 들어가면 현재 기본 호출 규칙을 볼 수 있다.

또한 밑의 코드처럼 함수 별로 호출규칙을 설정할 수도 있다. (호출규칙앞에 언더바를 2번 넣어준다.)

int __stdcall funcA() {
	return 0;
}

'CS 지식' 카테고리의 다른 글

캐시 메모리  (0) 2021.11.08
메모리  (0) 2021.11.08
endianness (엔디안)  (0) 2021.10.23
코드, 데이터, 힙, 스택 영역  (0) 2021.10.23
어셈블리 관련 정리(x86)  (0) 2021.10.15