繁体   English   中英

参数如何传递给 Linux 系统调用? 通过寄存器还是堆栈?

[英]How are parameters passed to Linux system call ? Via register or stack?

我试图通过阅读Robert Love 的 Linux Z6FF9F64444AC481623B444125AC481623B4 开发来了解 Linux kernel 的内部结构。

在第 74 页上,他说将 arguments 传递给syscall的最简单方法是通过:

不知何故,用户空间必须在陷阱期间将参数传递给 kernel。最简单的方法是通过传递系统调用号的相同方式:参数存储在寄存器中。 在 x86-32 上,寄存器 ebx、ecx、edx、esi 和 edi 按顺序包含前五个 arguments。

现在这困扰着我有几个原因:

  1. 所有系统调用都使用asmlinkage选项定义。 这意味着 arguments总是在堆栈而不是寄存器中找到 那么,这些与寄存器有关的业务是什么?
  2. 在执行系统调用之前,可能会将值复制到 kernel 堆栈中。 我不知道为什么这会有效,但它可能是一种可能性。

(此答案适用于 32 位 x86 Linux 以匹配您的问题;对于 64 位 x86 和其他架构,情况略有不同。)

正如 Love 所说,参数是从用户空间的寄存器中传递的。

当用户空间使用int $0x80调用系统调用时,kernel 系统调用入口代码获得控制权。 这是用汇编语言编写的,例如可以在这里看到。 该代码所做的一件事是从寄存器中获取参数并将它们压入堆栈,然后调用相应的 kernel sys_XXX() function(用 C 语言编写)。 所以这些函数确实希望它们的 arguments 在堆栈上。

尝试将参数从用户空间传递到堆栈上的 kernel 是行不通的。 当进行系统调用时,CPU 切换到单独的 kernel 堆栈,因此必须将参数从用户空间堆栈复制到 kernel 堆栈,这有点复杂。 即使对于只需要几个数字 arguments 并且根本不需要访问用户空间 memory 的非常简单的系统调用,它也必须完成(例如考虑close() )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM