[ASM] 64bit 환경에서의 레지스터와 리눅스 함수 호출 규약
42Seoul/그 외

[ASM] 64bit 환경에서의 레지스터와 리눅스 함수 호출 규약

libasm은 맥 OS 64bit 환경에서 인텔 어셈블리를 이용하여 진행되기 때문에, 이를 기준으로 정리하였습니다.

 

 

범용 레지스터

우선, 16bit의 레지스터는 각 레지스터 이름의 약자로 이루어져 있습니다(ex. AX = accumulator register). 여기서 32bit 레지스터들은 앞에 E(extended) 문자가 추가되고, 64bit는 R문자가 추가됩니다.

 

64bit 환경에서는 아래의 레지스터들 외에, r8~r15의 레지스터 8개를 추가로 가집니다

레지스터 accumulator base counter data stack pointer stack base pointer src dest
16bit AX BX CX DX SP BP SI DI
32bit EAX EBX ECX EDX ESP EBP ESI EDI
64bit RAX RBX RCX RDX RSP RBP RSI RDI

 

 

시스템 호출(syscall) 시 범용 레지스터

다음은, 리눅스에서 system call로 함수를 불러왔을 때, 범용 레지스터들의 상태입니다.

시스템 호출 번호 rax 함수의 syscall 번호를 가짐 (ex. exit() = 0x2000001)
반환 주소 rcx syscall을 호출했던 응용프로그램의 return 주소를 가짐. syscall이 끝난 후, return 주소를 rcx의 값으로 채움.
레지스터 플래그 r11 이전 플래그 레지스터. syscall이 끝난 후, 플래그를 r11의 값으로 채움.
매개변수 rdi (첫 번째 인자)
rsi (두 번째 인자)
rdx (세 번째 인자)
r10 (네 번째 인자)
r8 (다섯 번째 인자)
r9 (여섯 번째 인자)
 

 

 

함수 호출 규약

리눅스에서 함수 호출 시, 매개변수는 rdi, rsi, rdx, rcx, r8, r9 레지스터에 순서대로 넘겨지고, 6개 이상의 매개 변수를 넘겨주어야 할 때는, 스택을 이용합니다.

 

반환 값은 일반적으로 rax 레지스터로 넘겨집니다.

정수 rax (하위 64bit)
rdx (상위 64bit)
실수 xmm0 (하위 128bit)
xmm1 (상위 128bit)

 

함수 호출 전에, 위와 같은 rax나 매개변수 레지스터들이 비어있지 않으면 오류가 발생할 수 있습니다.