【问题标题】:What is the use of EAX register in the context of system calls in Linux?在 Linux 的系统调用上下文中,EAX 寄存器的用途是什么?
【发布时间】:2017-12-07 10:09:12
【问题描述】:

在教科书Linux Kernel Development by Robert Love中提到(第101页):

返回值也通过寄存器发送到用户空间。在 x86 上,它 写入eax寄存器。

在教科书The Linux Programming Interface by Michael Kerrisk中提到(第88页):

由于所有系统调用都以相同的方式进入内核,内核 需要一些识别系统调用的方法。为了允许这一点, 包装函数将系统调用号复制到特定的 CPU 注册 (%eax)。

那么,EAX寄存器在系统调用中的作用,我能得出什么结论呢?

当内核遇到系统调用时,它会将系统调用号复制到 EAX 寄存器中,该寄存器中的值在系统调用返回时被系统调用的返回值替换。这个结论正确吗?

【问题讨论】:

    标签: linux linux-kernel


    【解决方案1】:

    X86 Assembly/Interfacing with Linux

    进行系统调用

    要使用中断进行系统调用,您必须通过所有必需的 通过将它们复制到通用目的中来向内核提供信息 注册。

    每个系统调用都有一个固定编号(注意:int $0x80syscall 之间的编号不同!)。您可以通过写入数字来指定系统调用 进入 eax/rax 寄存器。

    大多数系统调用使用参数来执行它们的任务。那些参数 在制作之前通过将它们写入适当的寄存器来传递 实际调用。每个参数索引都有一个特定的寄存器。见 小节中的表,因为int $0x80 之间的映射不同 和syscall。参数按照它们出现的顺序传递 对应的 C 包装函数的函数签名。你可以 在每个 Linux API 中查找系统调用函数及其签名 文档,如参考手册(键入 man 2 open 以查看 开放系统调用的签名)。

    一切设置正确后,你调用中断使用 int $0x80syscall 内核执行任务。

    系统调用的返回/错误值写入eax/rax

    内核使用自己的堆栈来执行操作。用户栈 没有以任何方式被触及。

    总结一下:

    在用户空间:

    • 通过将参数写入指定寄存器来准备系统调用
    • 将系统调用号放入eax
    • 通过int $0x80syscall调用中断

    在内核空间中:

    • 内核从eax读取系统调用号
    • 从特定寄存器中读取参数
    • 执行任务(在它自己的堆栈上)
    • 将结果写入eax
    • 将控制权返回给用户空间

    再次进入用户空间:

    • 可以在eax寄存器中找到中断的结果

    【讨论】:

      猜你喜欢
      • 2018-01-21
      • 2021-04-27
      • 2017-06-03
      • 2011-08-15
      • 2017-02-04
      • 2020-01-18
      • 1970-01-01
      • 2013-02-11
      • 2016-06-08
      相关资源
      最近更新 更多