호출 규약

2021. 10. 25. 16:16C++

호출 규약이란 함수를 호출하는 방식에 대한 약속이다.
즉 함수를 호출하는 곳과 호출 당하는 곳, 이 둘이 함수 처리를 동일하게 하기 위해서 만들어진 것이다.
이것은 혼자 프로그래밍할때는 크게 중요하지 않지만,
콜백함수를 쓰는등 외부 API / 라이브러리를 사용할 때 알아두어야 한다.
 
여러가지 호출 규약들이 있는데, 
이들은 인자 전달 방법(매체), 인자 전달 순서, Stack frame 정리 방법
에 따라 나뉜다.
 
인자 전달 방법은 함수를 호출할 때 어떤 공간으로 인자를 넘길 것인지를 말한다.
stack 메모리에 저장하여 넘길 수도 있고, 레지스터 메모리에 넣어 전달하는 방법도 있다.
 
인자 전달 순서는 말 그대로 오른쪽에 있는 인자부터 전달할건지 왼쪽에 있는 인자부터 전달할건지를 말한다.
대부분 RTL (Right To Left) 방식이다.
 
stack frame 정리 방법은,
함수가 종료되었을 때 인자가 있는 공간을 호출자(Caller)와 피호출자(Callee) 중
누가 이 공간을 정리할지를 결정하는 것이다. 각각의 메커니즘은..
호출자가 정리할 경우: 호출한 함수가 종료된 후, 연산으로 esp를 내려준다.
피호출자가 정리할 경우: 반환시 (어셈블리 ret명령) 크기를 인자로 넣어 esp를 내려준다.
또한 호출자가 stack frame을 정리할 경우에만 함수에 가변 인자를 사용할 수 있다.
 
아래는 대표적인 호출 규약이다.
x86 아키텍쳐의 대부분 C컴파일러는 cdecl 호출 규약을 사용하고 있다.

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

 
비쥬얼 스튜디오에서 속성 - C/C++ - 고급 - 호출 규칙으로 들어가면 현재 기본 호출 규칙을 볼 수 있다.
또한 밑의 코드처럼 함수 별로 호출규칙을 설정할 수도 있다. (호출규칙앞에 언더바를 2번 넣어준다.)

int __stdcall funcA() {
	return 0;
}

'C++' 카테고리의 다른 글

비트맵(.bmp) 파일 구조  (0) 2022.01.06
[C/C++] 파일 패킹  (0) 2022.01.06
[C/C++] 파일 입출력  (0) 2022.01.06
C언어 문자열 처리  (0) 2022.01.06
C/C++ 시간을 측정하기  (0) 2022.01.06