[libasm] Assembly - 시스템 콜

Park Sejin·2021년 3월 29일
1
post-thumbnail

시스템 콜은 사용자와 커널 사이의 인터페이스를 위한 API이다. 우리는 이미 시스템 콜을 사용했다. 스크린에 출력하는 sys_write과 프로그램에서 탈출하는 sys_exit가 시스템 콜이다.

macOS는 리눅스와 시스템 콜 번호가 다르다.

macOS의 시스템 콜 번호는 리눅스에서 사용하는 시스템 콜 번호와 다르다.(e.g. 'write'은 macOS에서는 '0x2000004'이지만 리눅스에서는 '1'이다.) 시스템 콜 번호는 오프셋 0x200000를 추가해야 한다. macOS는 네 가지의 시스템 콜 클래스를 가지고 있기 때문이다. 시스템 콜 번호의 상위 비트는 시스템 콜의 클래스를 나타내며 write, exit의 경우는 SYSCALL_CLASS_UNIX이므로 상위 비트는 2이다. 그러므로 모든 Unix 시스템 콜은 (0x200000 + unix syscall #)이다.

macOS 시스템 콜

프로그램에서 macOS 시스템 콜을 사용하는 방법은 아래와 같다.

  • 시스템 콜 번호를 rax 레지스터에 저장한다.
  • 시스템 콜의 인자를 rdi, rsi, rdx, 등등에 저장한다.
  • syscall로 시스템 콜을 호출한다.
  • 리턴이 rax 레지스터에 저장된다.

❗️   위의 방법은 64비트 macOS 환경에서 시스템 콜을 호출하는 방법이다.

exit 시스템 콜을 사용하는 코드

mov rax, 0x2000001 ; 시스템 콜 번호 (exit)
mov rdi, 0	   ; exit 함수의 파라미터에 0을 저장한다.
		   ; 그렇지 않으면 프로그램 종료 시 exit code를 리턴한다.
syscall		   ; 시스템 콜 호출

write 시스템 콜을 사용하는 코드

mov	rdx, 4		; 메세지 길이
mov	rsi, msg	; 출력할 메세지
mov	rdi, 1		; 파일 디스크립터(표준출력)
mov	rax, 0x2000004	; 시스템 콜 번호 (write)
syscall			; 시스템 콜 호출

예제

아래의 예제는 키보드로 숫자를 읽어서 스크린에 출력하는 코드이다.

❗️   64비트 Intel macOS에서 동작하는 코드이다.

section .data
	userMsg	db 'Please enter a number: '
	lenUserMsg equ $ - userMsg
	dispMsg db 'You have entered: '
	lenDispMsg equ $ - dispMsg

section .bss		; 초기화 되지 않은 데이터
	num resb 5

section .text
	global _main

_main:
	mov	rax, 0x2000004
	mov	rdi, 1
	mov	rsi, userMsg
	mov	rdx, lenUserMsg
	syscall

	mov	rax, 0x2000003
	mov	rdi, 2
	mov	rsi, num
	mov	rdx, 5
	syscall

	mov	rax, 0x2000004
	mov	rdi, 1
	mov	rsi, dispMsg
	mov	rdx, lenDispMsg
	syscall

	mov	rax, 0x2000004
	mov	rdi, 1
	mov	rsi, num
	mov	rdx, 5
	syscall

	mov	rax, 0x2000001
	mov	rdi, 0		; exit 함수의 파라미터에 0을 저장한다.
    				; 그렇지 않으면 프로그램 종료 시 exit code를 리턴한다.
	syscall

코드를 컴파일하고 실행하면 아래의 결과를 확인할 수 있다.

Please enter a number:
1234
You have entered:1234

출처

tutorialspoint.com
Making system calls from Assembly in Mac OS X
Learning NASM on macOS

0개의 댓글