[기술면접/C,C++] 함수 호출 규약(Calling Convention)

김현아·2025년 8월 26일

기술면접

목록 보기
3/14

컴파일러가 함수 호출 시 인자(매개변수)를 어떻게 전달하고, 스택을 누가 정리할지를 정의한 규칙

  1. 스택 프레임(Stack Frame)
    함수가 호출도리 때 지역변수, 매개변수, 복귀 주소(return address)등을 저장하기 위해 스택에 생성되는 메모리 구조

구성요소

  • 매개변수(Parameter)
  • 복귀 주소(Return Address)
  • 저장된 레지스터(Saved Registers)
  • 지역변수(Local Variables)

대표적인 호출 규약
1) cdecl(C Declaration)

  • 사용 환경 : 주로 C언어에서 기본으로 사용되는 규약(특히 x86환경)
  • 인자 전달 순서 : 오른쪽 -> 왼쪽 순서로 스택에 푸시
  • 인자 전달 방법 : 스택을 이용
  • 스택 정리 : 호출자(Caller)가 함수 호출 후 스택을 정리
  • 가변 인자 : 지원(ex:printf,scanf)
    => 호출자가 스택을 정리 -> 가변 인자 지원

2) stdcall (Standard Call)

  • 사용 환경 : Windows API에서 주로 사용
  • 인자 전달 순서 : 오른쪽 ->왼쪽 순서로 스택에 푸시
  • 인자 전달 방법 : 스택을 이용
  • 스택 정리 : 피호출자(Callee)가 스택을 정리
  • 가변 인자 : 지원하지 않음
  • 함수 이름 규칙 : 컴파일 시 함수명 뒤에@n이 붙음(n은 바이트 단위 인자 크기)
    => 피호출자가 스택을 정리 -> Windows API에서 주로 사용

Q. 호출 규약을 사용하는 이유
(1) 호출자와 피호출자 간의 일관성 유지
: 호출자가 인자를 전달하는 방식과 피호출자가 받는 방식이 다르면, 데이터가 꼬여서 실행오류를 발생한다 따라서 인자를 어디에 둘지(스택/레지스터), 누가 스택을 정리할지를 정해놓는 것이 필수다.
(2) 플랫폼/언어 간 호환성 확보
: 운영체제마다 규약이 달를 수 있고, C/C++같은 언어는 여러 규약을 지원하여 OS API, 라이브러리, 어셈블리 코드와도 맞춰서 쓸 수 있도록 한다
(3) 가변 인자 함수 지원
: printf, scnaf 같은 함수는 인자의 개수가 매번 다르다. 이럴 경우 호출자가 스택을 정리(cdecl)해야 사변 인자 처리에 문제가 생기지 않는다.(callee가 스택을 정리한다면 인자의 개수를 알 수 없어 에러가 발생한다.)
(4) 최적화 목적
: 어떤 규약은 성능 최적화를 위해 레지스터를 활용한다.

  • fastcall : 일부 인자를 레지스터(ECX, EDX)에 전달 -> 스택 접근 비용 줄임
  • vectorcall : SIMD 레지스터(SMM, YMM)에 인자 전달 -> 벡터 연산에 최적화

#추가 참고 사이트
https://blog.naver.com/work1989/221275066623

0개의 댓글