在教科书Linux Kernel Development by Robert Love中,提到(第101页):
返回值也通过寄存器发送到用户空间。在x86上,它 被写入eax寄存器。
在教科书The Linux Programming Interface by Michael Kerrisk中,提到了(第88页):
由于所有系统调用都以相同的方式进入内核,即内核 需要一些识别系统调用的方法。允许这个, 包装函数将系统调用号复制到特定的CPU中 注册(%eax)。
那么,我可以在系统调用中得出EAX寄存器的实用结论吗?
当内核遇到系统调用时,它会将系统调用号复制到EAX寄存器,为此,寄存器中的值将被系统调用返回时系统调用的返回值替换。这个结论是否正确?
答案 0 :(得分:1)
X86 Assembly/Interfacing with Linux
进行系统调用
要使用中断进行系统调用,必须传递所有必需的内容 通过将它们复制到通用目的来向内核提供信息 寄存器。
每个系统调用都有一个固定的数字(注意:
int $0x80
和syscall
之间的数字不同!)。您可以通过编写数字来指定系统调用 进入eax / rax寄存器。大多数系统调用都会使用参数来执行任务。那些参数 通过在制作之前将它们写入适当的寄存器来传递 实际的电话。每个参数索引都有一个特定的寄存器见 由于映射在
int $0x80
之间不同,因此子节中的表格 和syscall
。参数按它们出现的顺序传递 相应的C包装函数的函数签名。你可以 在每个Linux API中查找系统调用函数及其签名 文档,如参考手册(类型man 2打开看到 open syscall的签名。)完成所有设置后,您可以使用中断调用中断
int $0x80
或syscall
并且内核执行任务。系统调用的返回/错误值将写入
eax
/rax
。内核使用自己的堆栈来执行操作。用户堆栈 没有任何接触。
总结一下:
在用户空间:
eax
int $0x80
或syscall
在内核空间中:
eax
eax
再次在用户空间中:
eax
寄存器