2

我想知道 exec() 系统调用参数存储在哪些寄存器中。

我首先运行了一个简单的 C 程序,它执行 exec 系统调用并获取其对象转储,发现 RDI 被用于包含要执行的进程的参数,并且 syscall 指令被用于在内核中调用 execve。我是在 64 位 Ubuntu 12.04 操作系统中完成的

然后我在 QEMU 上运行的 Ubuntu 11.10 OS(32 位)上运行了这个程序。但是现在在没有 0x80 的对象转储中断中被使用并且参数在 EBX 中。

我在两个方面感到困惑..为什么在一个地方使用 int80 而在另一个地方使用 syscall 以及如何选择 execve 系统调用的寄存器?

4

1 回答 1

0

您所看到的是,不同的芯片架构在向正在运行的操作系统发出服务请求时使用不同的系统调用约定。这些约定是操作系统定义的ABI (应用程序二进制接口)的一部分——ABI 定义的其他内容包括:

  • 用于将参数传递给函数的寄存器(和/或堆栈布局)

  • 哪些寄存器函数可以用作暂存空间,而哪些寄存器在返回时必须恢复到以前的值

  • 处理器地址空间内程序的(虚拟)内存布局

请记住,尽管它们通常都由相同的物理处理器支持(出于向后兼容性的原因),但英特尔 64 位 (IA64) 和 32 位 (IA32) 架构仍然是分开的,具有不同的(如果重叠)寄存器可用,并且具有不同的 ABI . 正如您所注意到的,这两个 ABI 在系统调用的参数放置和向内核发出系统调用发出信号的方式上都不同。

如今,操作系统 ABI 通常由提供特定芯片架构的公司定义(至少作为建议),因此在给定架构上运行的所有(或大多数)操作系统通常都提供相同的 ABI,但情况并非总是如此——在完全相同的硬件上运行的不同操作系统之间仍然可以找到您注意到的类型差异。

于 2013-01-18T15:07:54.167 回答