hhkb.dev

BLOG

2025-10-11 / 어셈블리 · 05

System V AMD64 ABI와 스택 프레임

함수 호출은 마음대로 값을 넘기면 안 된다. 외부 라이브러리와 맞물려 돌아가려면, 레지스터와 스택을 쓰는 공통 규칙을 따라야 한다. 리눅스 64비트 환경에서는 그 기준이 System V AMD64 ABI다.

1. 함수 호출 규약(Calling Convention)

함수 인자는 스택보다 빠른 레지스터를 먼저 사용해 전달한다. 기본 순서는 아래와 같다.

  1. RDI
  2. RSI
  3. RDX
  4. RCX
  5. R8
  6. R9

7번째 인자부터는 스택으로 넘어간다. 이 순서를 어기면 함수가 엉뚱한 값을 읽고 오작동할 수 있다.

2. 스택 프레임(Stack Frame)

스택 프레임은 함수가 실행되는 동안만 잡히는 독립 작업 공간이다. 보통 프롤로그에서 만들고, 에필로그에서 정리한다.

2.1. 프롤로그(생성)

push rbp        ; 이전 함수의 베이스 포인터(RBP) 백업
mov rbp, rsp    ; 현재 스택 포인터(RSP)를 새로운 기준점(RBP)으로 설정
sub rsp, 0x10   ; 지역 변수 공간 확보

2.2. 에필로그(해제)

leave           ; RBP를 복구하고 스택 프레임 정리 (mov rsp, rbp + pop rbp)
ret             ; 스택에 저장된 복귀 주소로 점프

최신 컴파일러는 최적화를 위해 RBP를 생략하는 경우도 있다. 그래도 프레임을 잡고 정리하는 기본 흐름 자체는 크게 달라지지 않는다.