退出系统调用(60)
本课属于 Coddy Assembly 学习旅程的“基础知识”单元。第 32 课,共 45 课。
对任何程序来说,最重要的系统调用是 exit。没有它,程序会一直运行下去,或者在到达内存末尾时崩溃。
exit 系统调用的编号是 60。
语法:
mov rax, 60 ; exit 的系统调用号
mov rdi, 0 ; 退出码(0 = 成功)
syscall ; 请求操作系统退出当你执行 syscall 且 rax = 60 时,会发生什么:
- CPU 跳转到 Linux 内核
- 内核看到:“使用代码 0 退出的系统调用”
- 内核终止你的程序
- 内核将控制权交还给 shell 或操作系统
退出代码 0 表示成功:程序已完成运行,且没有错误。退出代码 1 到 255 表示不同的错误。你可以选择任意数字来表示哪里出了问题。
退出码为什么重要:
程序退出后,shell(终端)会保存退出码。你可以用以下命令查看:
./myprogram
echo $? ; Prints the exit code这适用于:
- 检查程序是否成功的脚本
- 调试(不同错误使用不同代码)
- 将多个程序串联起来
一个完整的最简程序:
section .text
global _start
_start:
mov rax, 60 ; 退出系统调用
mov rdi, 0 ; 退出码 0(成功)
syscall这个程序不会产生任何可见效果。它只是成功退出。但这是一个有效且完整的程序。
我们来讲讲 global _start 和 _start: 是什么。
| 代码 | 含义 | 用途 |
|---|---|---|
global _start | 告诉链接器程序从哪里开始 | 没有它,链接器就不知道哪个标签是入口点 |
_start: | 标记代码开头的标签 | CPU 从这里开始执行 |
你不需要记住这些细节。只要知道,每个 main.asm 都必须在你的代码前包含这两行。你会在每个程序中使用它们。
如果忘记了退出系统调用,会发生什么?
如果不包含退出系统调用,CPU 会继续执行代码之后内存中的任意无用数据。这通常会导致段错误(崩溃)或完全出乎意料的行为。程序无法正常结束。
始终以 exit 系统调用结束程序。
挑战
添加退出系统调用,退出代码为 5。
打印消息 "Exiting with code 5" 的代码已经为你提供。你现在不需要理解它。我们会在第 5 章讲解这部分内容。
你只需要在末尾添加退出系统调用。
亲手试试
section .data
msg db 'Exiting with code 5', 0x0a
msgLen equ $ - msg
section .text
global _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, msgLen
syscall
; TODO:添加退出系统调用,退出码为 5
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
基础知识中的所有课
自己练习: Assembly 在线编辑器