Write Syscall (1)
Coddy Assembly 여정의 기초 섹션에 포함된 레슨 — 45개 중 35번째.
프로그램을 종료하는 방법은 이미 알고 있습니다. 하지만 아무런 메시지 없이 종료하는 것은 그리 유용하지 않습니다. 사용자가 무언가를 볼 수 있도록 프로그램이 결과를 출력하기를 원할 것입니다.
그러기 위해서는 write syscall이 필요합니다.
write syscall이란 무엇인가요?
write syscall은 운영체제에게 화면에 텍스트를 출력하거나(또는 파일에 쓰거나) 하도록 지시합니다. 이것이 프로그램이 출력을 생성하는 방법입니다.
write의 시스템 호출 번호는 1입니다.
write의 작동 방식:
exit 시스템 호출(인수가 하나만 필요함)과 달리, write는 세 개의 인수가 필요합니다:
| 인수 | 레지스터 | 설명 | 예시 |
|---|---|---|---|
| 파일 디스크립터 | rdi | 출력할 위치 (1 = 화면) | mov rdi, 1 |
| 버퍼 주소 | rsi | 텍스트가 저장된 메모리 위치 | mov rsi, message |
| 바이트 수 | rdx | 출력할 바이트 수 | mov rdx, 13 |
작동 중인 write syscall:
mov rax, 1 ; write를 위한 시스템 호출 번호
mov rdi, 1 ; 파일 디스크립터 1 = stdout (화면)
mov rsi, msg ; 출력할 문자열의 주소
mov rdx, 13 ; 출력할 바이트 수
syscall ; OS에 출력을 요청화면에 메시지를 출력하려면 5줄이 필요합니다. 먼저, 쓰기(write)를 위해 시스템 콜 번호 1을 rax에 넣습니다. 그런 다음, OS에 화면에 출력하도록 알리기 위해 1을 rdi에 넣습니다.
다음으로, 문자열(msg)의 주소를 rsi에 넣습니다. 그 후, 바이트 수(13)를 rdx에 넣습니다. 마지막으로, syscall을 실행하여 OS에 출력을 요청합니다.
write를 실행할 때 일어나는 일:
- CPU가 Linux 커널로 진입합니다
- 커널은 "write syscall"임을 확인합니다
- 커널은
rdi(어디에 쓸지),rsi(텍스트가 어디에 있는지), 그리고rdx(몇 바이트인지)를 읽습니다
- 화면에 텍스트를 출력합니다
- 프로그램으로 제어권을 반환합니다
문자열과 함께 구성하기:
section .data
msg db 'Hello', 0x0a ; 개행 문자가 포함된 문자열
section .text
global _start
_start:
mov rax, 1 ; write 시스템 콜
mov rdi, 1 ; 표준 출력(stdout)
mov rsi, msg ; 문자열의 주소
mov rdx, 6 ; 길이 (Hello + 개행 문자 = 6 바이트)
syscall
mov rax, 60 ; exit 시스템 콜
mov rdi, 0
syscall이 프로그램은 Hello를 출력하고 종료됩니다.
챌린지
"Hi" 메시지와 개행 문자를 출력하는 프로그램을 작성하세요. write 시스템 호출(syscall)을 사용하세요.
문자열은 테스트 하니스에 이미 정의되어 있습니다. 시스템 호출(syscall) 설정 부분만 작성하면 됩니다.
직접 해보기
section .data
msg db 'Hi', 0x0a
msgLen equ $ - msg
section .text
global _start
_start:
; TODO: msg를 출력하기 위해 write 시스템 콜을 설정하고 호출합니다
; rax=1, rdi=1, rsi=msg, rdx=msgLen을 사용하세요
; 프로그램을 종료합니다
mov rax, 60
mov rdi, 0
syscall이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.