Assembly

x86 assembly system call

jdaemanv2 2021. 12. 11. 11:32

[1. System call]

시스템 콜은 운영체제(커널) 이 제공하는 서비스이다.

예를 들어, C 언어에서 파일을 열고 데이터 작성 및 저장 시, 물리 디스크에 직접 저장하는 코드를 작성하지 않고,

운영체제가 제공하는 함수, 이 경우에서는 write() 같은 시스템 콜을 활용 할 수 있다.

 

 

[2. x86 system call]

assembly 로 작성한 코드도 어셈블러에 의해 컴파일(어셈블) 된 뒤

링커에 의해 링킹 후 실행파일이 되어 하나의 프로그램이 된다.

따라서 assembly 에서도 커널이 제공하는 시스템 콜을 사용 할 수 있다.

 

다만, 시스템 콜 호출을 위한 지켜야 할 규칙이 있다.

시스템 콜은 호출을 위한 시스템 콜 번호가 정해져 있다.

32bit 와 64bit 에서 시스템 콜 번호가 다르긴 하지만,

이러한 시스템 콜 번호를 특정 레지스터에 저장 및, 기타 매개변수들을 정해진 레지스터에 저장 한 후

인터럽트를 발생시키는 것이다.

 

그래서 시스템 콜을 보통 software interrupt 라고 부르기도 한다.

 

 

[3. System call table 및 interrupt]

앞서, 시스템 콜 번호는 32bit 와 64bit 에서 다르다고 하였다.

그래서 32bit 는 아래를 참조하고

Linux System Call Table (nps.edu)

 

64bit 는 아래를 참조하도록 한다.

Linux System Call Table for x86 64 · Ryan A. Chapman (rchapman.org)

 

또한, system call 호출을 위한 인터럽트 발생에서

legacy 한 방식은

int 0x80 이라는 assembly 코드를 작성하는 것이다.

 

하지만 이러한 방식보다는 아래와 같은 방법이 더 적합하다.

x86-32: sysenter

x86-64: syscall

 

참조: assembly - What is better "int 0x80" or "syscall" in 32-bit code on Linux? - Stack Overflow

 

 

[4. Example]

아래 예제는 x86-64 이며, intel syntax 로 작성하였다.

이후에도 intel syntax 로 작성한다.

동작은 rcx register 에 42 를 저장 후, exit(42) 를 호출하는 것이다.

 

$ vim exit.s

; exit(22)

section .text
        global _start

_start:
        xor rcx, rcx
dummy:
        add rcx, 20
        inc rcx

        cmp rcx, 21
        je dummy

        mov rax, 60
        mov rdi, rcx
        syscall

$ nasm -f elf64 exit.s

$ ld -o exit.o exit

$ ./exit ; echo $?

 

42 를 확인 할 수 있다.