👩🏻‍💻기초지식/C++

[C++] 함수 호출 규약이란? cdecl, stdcall, fastcall, thiscall 의 차이들?

공대 컴린이 2023. 8. 17. 11:35
728x90

함수 호출 규약 (Calling Convention)

- 함수 호출 규약이란 어떤 함수를 호출할 때, 그 함수의 파라미터(인자)를 어떤 방식으로 전달하는가에 대한 하나의 약속을 말한다.
- 함수 호출 규약은 컴파일러에서 설정할 수 있고, 일부 함수 호출 규약은 프로그래머가 직접 명시적으로 지정할 수 있다.
- 함수 호출 규약을 지정하지 않으면, 기본적으로 CDECL 규약이 사용된다.
 

함수 호출 규약 종류

인자 전달 순서 : 왼쪽인자 → 오른쪽 인자 or 오른쪽 인자 → 왼쪽 인자

- 함수 인자들에 대해 어떤 순서로 스택에 쌓을 것인지

인자 전달 방법 : 스택 or 레지스터

스택 프레임을 정리하는 방법 : 함수 호출자[caller] or 함수 피호출자[callee]

- 함수 종료 후 스택을 누가 정리할 것인지

 

함수 호출 규약이 필요한 이유

매개변수 전달 방식 표준화

- 매개변수 전달 방식을 표준화하여 서로 다른 컴파일러와 링커 간에도 호환성을 유지할 수 있도록 한다.

- 인자를 스택에 푸시하는 방식이나 레지스터를 사용하는 방식 등에 따라 함수 호출 방식이 달라지므로, 이러한 방식을 표준화하

여 함수 호출 규약을 정의한다.

성능 최적화

- 함수 호출 규약은 함수 호출과 반환을 최적화하여 성능을 향상시킨다.

- 예를 들어, 레지스터를 사용하여 인자를 전달하거나 스택을 사용하여 전달하는 방식 등에 따라 함수 호출 시간이 달라질 수 있다.

- 특히 이러한 최적화는 대규모 프로그램에서 함수 호출 횟수가 많은 경우 성능에 큰 영향을 미친다.

운영체제와의 호환성

- 운영체제는 함수 호출 규약을 기반으로 메모리 할당과 해제를 수행하며, 스택 프레임 구조를 구성한다.

- 따라서 함수 호출 규약을 잘 지키지 않으면, 프로그램 실행 중 다양한 문제가 발생할 수 있다.

정리하면, 함수 호출 규약은 프로그램의 이식성, 호환성, 성능 등을 보장하기 위해 필요한 중요한 규칙이다.

 

cdecl, stdcall, fastcall, thiscall 

- 함수 호출 규약에서 핵심적인 규약 4가지 입니다.

cdecl

- 인자 전달 순서 : 가장 오른쪽 인자 → 가장 왼쪽 인자

- 인자 전달 방법 : 스택 메모리를 이용

- 스택 프레임 정리 : Caller(호출자)가 스택 프레임을 정리

- 가변 인자 사용여부 : 가변인자 사용 가능 (장점)

  (가변인자란 printf 처럼 매개변수의 개수가 정해지지 않는 함수를 말한다. 가변인자는 Caller가 인자를 정리하는 함수규약에서

사용할 수 있다.)

- 특징

- CDECL 규약은 대부분의 C 함수 호출 규약에서 사용되고, Caller가 직접 스택을 정리하는 방식이 특징적이다.

 

stdcall

- 인자 전달 순서 : 가장 오른쪽 인자 → 가장 왼쪽 인자

- 인자 전달 방법 : 스택 메모리를 이용

- 스택 프레임 정리 : Callee(피호출자)가 스택 프레임을 정리

- 가변 인자 사용여부 : 가변인자 사용 불가능

- 특징

- Win32 API 호출 규약 등에서 사용된다.

 

fastcall

- 인자 전달 순서 : 레지스터는 왼쪽 인자 → 오른쪽 인자, 스택에서는 오른쪽 인자 → 왼쪽 인자

- 인자 전달 방법 : 처음 2개 매개변수는 레지스터(EDX, ECX)를 이용, 3개의 매개변수부터는 스택을 이용

- 스택 프레임 정리 : Callee(피호출자)가 스택프레임을 정리

- 가변 인자 사용여부 : 가변인자 사용 불가능

- 특징

- 인라인 함수에서 사용된다.

- fastcall 호출 규약은 레지스터 내 하나 이상의 인수를 통과시키며, 호출에 필요한 메모리 접근의 수를 줄인다.

- fastcall은 레지스터를 직접 이용하기 때문에 속도가 빠르다.

 

thiscall

- 인자 전달 순서 : 가장 오른쪽 인자 → 가장 왼쪽 인자

- 인자 전달 방법 : 레지스터(ECX)를 이용

- 스택 프레임 정리 : Callee(피호출자)가 스택프레임을 정리

- 특징

- 클래스 멤버 함수에서 정의할 수 있는 규약이다.

- 첫 번째 매개변수로 this 포인터를 전달하여, 나머지 매개변수들을 스택으로 저장하지만 그것을 this 포인터로 연결하는 형식이다.

- 그러한 this 포인터는 레지스터에 저장된다.

- ECX 레지스터로 this 포인터가 전달된다는 것 말고는 stdcall과 동일하게 작동한다.


https://over-stack.tistory.com/23

 

C/C++ 함수의 호출 규약 (Calling Convention) with 어셈블리

안녕하세요, IT디자이너입니다. 이번 포스팅은 함수 호출 규약에 관하여 설명드리도록 하겠습니다. 소개해드릴 함수 호출 규약은 cdecl,stdcall,fastcall 입니다. 이 함수 호출 규약 말고도 여러가지의

over-stack.tistory.com

https://velog.io/@dnrgus1127/%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C-%EA%B7%9C%EC%95%BD

 

함수 호출 규약

Calling Convention, 해석하면 '함수 호출 규약' 이란 어떤 함수를 호출 할 때, 그 함수의 파라미터(인자)를 어떤 방식으로 전달하는가에 대한 하나의 약속이다.함수를 호출 할 때, 프로세스에 정의되

velog.io

 

728x90