如果系统调用需要一些 32 位参数,例如uid_t
or int
(对于文件描述符),unsigned int
甚至需要一些 16 位类型,我如何使用 64 位寄存器传递它们?
在使用该指令之前,是否需要将它们进行零扩展或符号扩展至 64 位syscall
?
如果我__X32_SYSCALL_BIT
在 RAX 中使用,使原始 64 位指针类型参数变成 32 位,我仍然需要使用相同的 64 位寄存器来传递参数,在这种情况下我需要对地址参数进行零扩展吗?
答案1
您应该对它们进行零扩展,但对于 x86-64 上 32 位值的常见情况,无需考虑它:将值存储在 32 位寄存器中会导致零扩展存储相应的64位寄存器(IE,movl $4, %edx
将 4 存储在rdx
) 中。 8 位和 16 位值应显式零扩展(movzbl
或movzwl
从 8 位或 16 位寄存器到 32 位寄存器,隐式零扩展到 64 位)。
实际上,对于非指针,系统调用实现只会读取低层n无论如何,您不应该看到任何实际差异,至少对于 32 位值而言。 (例如SYS_read
在前 32 位中使用垃圾进行调用RDI
不会产生错误,并且只考虑较低的 32 位。)我还没有检查如果您在__X32_SYSCALL_BIT
不清除指针的前 32 位的情况下设置会发生什么。