Lời gọi hệ thống write (1)
Thuộc phần Kiến thức nền tảng trong hành trình Assembly của Coddy. Bài học 35 trên 45.
Bạn đã biết cách thoát khỏi một chương trình. Nhưng thoát mà không thông báo thì chẳng hữu ích lắm. Bạn muốn chương trình in ra đầu ra để người dùng nhìn thấy nội dung nào đó.
Để làm vậy, bạn cần lời gọi hệ thống ghi (write syscall).
Gọi hệ thống write là gì?
Gọi hệ thống write yêu cầu hệ điều hành in văn bản ra màn hình (hoặc ghi vào tệp). Đây là cách chương trình tạo đầu ra.
Số syscall của write là 1.
Cách write hoạt động:
Khác với syscall exit (chỉ cần một đối số), write cần ba đối số:
| Đối số | Thanh ghi | Chức năng | Ví dụ |
|---|---|---|---|
| Mô tả tệp | rdi | Nơi ghi (1 = màn hình) | mov rdi, 1 |
| Địa chỉ bộ đệm | rsi | Nơi văn bản nằm trong bộ nhớ | mov rsi, message |
| Số byte | rdx | Số byte cần in ra | mov rdx, 13 |
System call write trong thực tế:
mov rax, 1 ; Số hiệu syscall cho write
mov rdi, 1 ; Bộ mô tả tệp 1 = stdout (màn hình)
mov rsi, msg ; Địa chỉ của chuỗi cần in ra
mov rdx, 13 ; Số byte cần in ra
syscall ; Yêu cầu hệ điều hành in raĐể in một thông báo ra màn hình, ta cần 5 dòng. Trước tiên, ta đặt số syscall 1 vào rax để ghi. Sau đó, ta đặt 1 vào rdi để báo cho hệ điều hành in ra màn hình.
Tiếp theo, chúng ta đưa địa chỉ của chuỗi (msg) vào rsi. Sau đó, chúng ta đưa số byte (13) vào rdx. Cuối cùng, chúng ta thực thi syscall để yêu cầu hệ điều hành in ra.
Điều gì xảy ra khi bạn thực thi write:
- CPU nhảy vào nhân Linux
- Nhân thấy: "write syscall"
- Nó đọc
rdi(nơi cần ghi),rsi(nơi chứa văn bản) vàrdx(số byte)
- Nó in văn bản ra màn hình
- Nó trả quyền điều khiển về chương trình của bạn
Kết hợp với một chuỗi:
section .data
msg db 'Hello', 0x0a ; chuỗi có ký tự xuống dòng
section .text
global _start
_start:
mov rax, 1 ; lời gọi hệ thống write
mov rdi, 1 ; stdout
mov rsi, msg ; địa chỉ của chuỗi
mov rdx, 6 ; độ dài (Hello + ký tự xuống dòng = 6 byte)
syscall
mov rax, 60 ; lời gọi hệ thống exit
mov rdi, 0
syscallChương trình này in ra Hello rồi thoát.
Thử thách
Viết chương trình in ra thông điệp "Hi", theo sau là ký tự xuống dòng. Sử dụng syscall write.
Chuỗi đã được định nghĩa sẵn trong test harness. Bạn chỉ cần viết phần thiết lập syscall.
Tự làm thử
section .data
msg db 'Hi', 0x0a
msgLen equ $ - msg
section .text
global _start
_start:
; TODO: Thiết lập và gọi syscall write để in ra msg
; Dùng rax=1, rdi=1, rsi=msg, rdx=msgLen
; Thoát chương trình
mov rax, 60
mov rdi, 0
syscallBài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Kiến thức nền tảng
3Lệnh đầu tiên: MOV
MOV là gì?MOV với giá trị tức thờiMOV từ thanh ghi sang thanh ghiMOV từ bộ nhớ sang thanh ghiMOV từ thanh ghi vào bộ nhớLEA: nạp địa chỉMOV với các kích thước khác nhauLuyện tập: hoán đổi thanh ghiÔn tập: thử thách MOV6Lời gọi hệ thống write
Lời gọi hệ thống write (1)Bộ mô tả tệp (rdi)Địa chỉ bộ đệm (rsi)Số byte (rdx)Ghép các phần lạiIn hai chuỗiKý tự xuống dòng rất quan trọngÔn tập: thiết lập writeTự luyện tập: Playground Assembly