본문으로 이동
주 메뉴
주 메뉴
사이드바로 이동
숨기기
둘러보기
대문
최근 바뀜
임의 문서로
~ldmsys
검색
검색
외관
로그인
개인 도구
로그인
현재 모든 문서는 작성 중입니다. 보시는 데 불편함이 있더라도 양해 부탁드립니다.
System V ABI 문서 원본 보기
문서
토론
한국어
읽기
원본 보기
역사 보기
도구
도구
사이드바로 이동
숨기기
작업
읽기
원본 보기
역사 보기
일반
여기를 가리키는 문서
가리키는 글의 최근 바뀜
문서 정보
외관
사이드바로 이동
숨기기
←
System V ABI
문서 편집 작업을 수행할 권한이 없습니다. 다음 이유를 확인해주세요:
요청한 작업은 다음 권한을 가진 사용자에게 제한됩니다:
사용자
.
문서의 원본을 보거나 복사할 수 있습니다.
'''System V ABI'''(System V Application Binary Interface)는 유닉스 계열 운영체제에서 실행 파일 형식, 데이터 타입 크기, 함수 호출 규약 등을 정의하는 규격이다. 현대의 64비트 UNIX 계열 (Linux, *BSD) 시스템에서는 주로 '''amd64(x86-64) System V ABI'''가 사용되기에 이 문서는 '''amd64(x86-64) System V ABI'''를 중심으로 설명한다. == amd64 System V ABI의 특징 == === 데이터 모델 (LP64) === amd64 System V ABI에서는 다음과 같은 LP64 데이터 모델을 사용한다. * <code>int</code> : 32비트 * <code>long</code>, <code>long long</code> : 64비트 * 포인터(<code>void *</code> 등) : 64비트 이는 C 코드에서 정수와 포인터 크기를 가정할 때 중요한 전제이다. === 함수 인자 전달 규칙 === 정수형, 포인터형 등 대부분의 스칼라 인자는 다음 순서의 레지스터로 전달된다. {| class="wikitable" ! 인자 번호 !! 사용 레지스터 |- | 1번째 인자 || RDI |- | 2번째 인자 || RSI |- | 3번째 인자 || RDX |- | 4번째 인자 || RCX |- | 5번째 인자 || R8 |- | 6번째 인자 || R9 |} * 7번째 인자부터는 스택에 8바이트 단위로 저장된 뒤 전달된다. * 부동소수점 인자(<code>float</code>, <code>double</code>)는 XMM0–XMM7 레지스터를 통해 전달되며, 정수 인자와는 별도로 순서가 관리된다. 스택은 함수 호출 시 16바이트 정렬(alignment)을 유지해야 하며, 컴파일러가 이를 맞추도록 코드를 생성한다. === 반환값 규칙 === * 대부분의 정수/포인터 반환값: RAX * 128비트까지의 일부 정수/구조체 반환: RAX와 RDX 조합 * 부동소수점 반환값: XMM0 더 큰 구조체 반환 등 특수한 경우에는 호출자가 반환 버퍼를 준비하고 포인터를 넘기는 방식 등이 사용된다. === 레지스터 보존 규약 === amd64 System V ABI는 어떤 레지스터를 누가 보존해야 하는지도 정의한다. * 호출자 저장(caller-saved): 함수 호출 시 덮어써져도 되므로, 필요한 경우 '''호출하는 쪽'''이 미리 저장해야 하는 레지스터 * 피호출자 저장(callee-saved): 함수가 종료될 때 원래 값이 유지되어야 하므로, '''호출되는 함수'''가 저장·복원해야 하는 레지스터 대표적인 규약은 다음과 같다. {| class="wikitable" ! 구분 !! 레지스터 |- | 호출자 저장 || RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, XMM0–XMM15 |- | 피호출자 저장 || RBX, RBP, R12, R13, R14, R15 |} RSP(스택 포인터)는 호출 전후에 일관되게 유지되어야 한다. == C 언어 예시 == 다음 예시는 정수 인자가 어떻게 레지스터와 스택으로 전달되는지 보여준다. <pre> int foo(int a, int b, int c, int d, int e, int f, int g); int caller(void) { return foo(1, 2, 3, 4, 5, 6, 7); } </pre> 위 호출에서 <code>foo</code>는 amd64 System V ABI에 따라 다음과 같이 인자를 받는다. * <code>a</code> → RDI (1번째 인자) * <code>b</code> → RSI (2번째 인자) * <code>c</code> → RDX (3번째 인자) * <code>d</code> → RCX (4번째 인자) * <code>e</code> → R8 (5번째 인자) * <code>f</code> → R9 (6번째 인자) * <code>g</code> → 스택 상의 슬롯 (7번째 인자) <code>foo</code>가 <code>int</code>를 반환하면, 그 값은 RAX에 담겨 <code>caller</code>로 전달된다. 부동소수점 인자의 경우: <pre> double add_double(double x, double y); double caller2(void) { return add_double(1.0, 2.0); } </pre> * <code>x</code> → XMM0 * <code>y</code> → XMM1 * 반환값(<code>double</code>) → XMM0
System V ABI
문서로 돌아갑니다.
검색
검색
System V ABI 문서 원본 보기
새 주제