我应该如何将 32 位参数传递给 x86_64 上的 Linux 系统调用?

我应该如何将 32 位参数传递给 x86_64 上的 Linux 系统调用?

如果系统调用需要一些 32 位参数,例如uid_tor int(对于文件描述符),unsigned int甚至需要一些 16 位类型,我如何使用 64 位寄存器传递它们?

在使用该指令之前,是否需要将它们进行零扩展或符号扩展至 64 位syscall

如果我__X32_SYSCALL_BIT在 RAX 中使用,使原始 64 位指针类型参数变成 32 位,我仍然需要使用相同的 64 位寄存器来传递参数,在这种情况下我需要对地址参数进行零扩展吗?

答案1

您应该对它们进行零扩展,但对于 x86-64 上 32 位值的常见情况,无需考虑它:将值存储在 32 位寄存器中会导致零扩展存储相应的64位寄存器(IEmovl $4, %edx将 4 存储在rdx) 中。 8 位和 16 位值应显式零扩展(movzblmovzwl从 8 位或 16 位寄存器到 32 位寄存器,隐式零扩展到 64 位)。

实际上,对于非指针,系统调用实现只会读取低层n无论如何,您不应该看到任何实际差异,至少对于 32 位值而言。 (例如SYS_read在前 32 位中使用垃圾进行调用RDI不会产生错误,并且只考虑较低的 32 位。)我还没有检查如果您在__X32_SYSCALL_BIT不清除指针的前 32 位的情况下设置会发生什么。

相关内容