写入系统调用(1)
本课属于 Coddy Assembly 学习旅程的“基础知识”单元。第 35 课,共 45 课。
你已经知道如何退出程序了。但静默退出并没有太大用处。你希望程序能打印输出,让用户看到一些内容。
为此,你需要 write 系统调用。
什么是 write 系统调用?
write 系统调用会告诉操作系统将文本打印到屏幕上(或写入文件)。程序就是通过它生成输出的。
write 的系统调用编号是 1。
write 的工作原理:
与 exit 系统调用(只需要一个参数)不同,write 需要三个参数:
| 参数 | 寄存器 | 作用 | 示例 |
|---|---|---|---|
| 文件描述符 | rdi | 写入的位置(1 = 屏幕) | mov rdi, 1 |
| 缓冲区地址 | rsi | 文本在内存中的位置 | mov rsi, message |
| 字节数 | rdx | 要打印多少字节 | mov rdx, 13 |
write 系统调用的实际应用:
mov rax, 1 ; write 的系统调用号
mov rdi, 1 ; 文件描述符 1 = stdout(屏幕)
mov rsi, msg ; 要打印的字符串的地址
mov rdx, 13 ; 要打印的字节数
syscall ; 请求操作系统打印要在屏幕上打印一条消息,我们需要 5 行代码。首先,我们将系统调用编号 1 放入 rax,用于写入。然后,我们将 1 放入 rdi,告诉 OS 在屏幕上打印。
接下来,我们将字符串的地址(msg)放入 rsi。然后,将字节数(13)放入 rdx。最后,我们执行 syscall,请求操作系统打印内容。
执行 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 系统调用。
测试框架已经为你定义好了字符串。你只需要编写系统调用的设置代码。
亲手试试
section .data
msg db 'Hi', 0x0a
msgLen equ $ - msg
section .text
global _start
_start:
; TODO: 设置并调用 write 系统调用,打印 msg
; 使用 rax=1、rdi=1、rsi=msg、rdx=msgLen
; 退出程序
mov rax, 60
mov rdi, 0
syscall这节课包含一个小测验。开始学习即可作答,并记录你的进度。
基础知识中的所有课
自己练习: Assembly 在线编辑器