炸鱼薯条德里克 Asked: 2019-02-07 17:17:16 +0800 CST2019-02-07 17:17:16 +0800 CST 2019-02-07 17:17:16 +0800 CST 我应该如何将 32 位参数传递给 x86_64 上的 Linux 系统调用? 772 如果系统调用需要一些 32 位参数,例如uid_t或int(用于文件描述符)unsigned int甚至一些 16 位类型,我如何使用 64 位寄存器传递它们? 在使用指令之前,我是否需要将它们零扩展或符号扩展为 64 位syscall? 如果我__X32_SYSCALL_BIT在 RAX 中使用,原来的 64 位指针类型参数变为 32 位,我仍然需要使用相同的 64 位寄存器来传递参数,在这种情况下我是否需要对地址参数进行零扩展? linux x86 1 个回答 Voted Best Answer Stephen Kitt 2019-02-08T04:33:34+08:002019-02-08T04:33:34+08:00 您应该对它们进行零扩展,但是对于 x86-64 上 32 位值的常见情况,无需考虑:将值存储在 32 位寄存器中会导致零扩展存储到相应的 64 位寄存器(即,movl $4, %edx存储 4 in rdx)。8 位和 16 位值应显式零扩展(movzbl或movzwl从 8 位或 16 位寄存器到 32 位寄存器,隐式零扩展至 64 位)。 实际上,对于非指针,系统调用实现无论如何都只会读取低n位,因此您不应该看到任何实际差异,至少对于 32 位值。(例如SYS_read,在前 32 位中使用垃圾调用RDI不会产生错误,并且只考虑低 32 位。)我还没有检查如果您在__X32_SYSCALL_BIT不清除指针的前 32 位的情况下设置会发生什么。
您应该对它们进行零扩展,但是对于 x86-64 上 32 位值的常见情况,无需考虑:将值存储在 32 位寄存器中会导致零扩展存储到相应的 64 位寄存器(即,
movl $4, %edx
存储 4 inrdx
)。8 位和 16 位值应显式零扩展(movzbl
或movzwl
从 8 位或 16 位寄存器到 32 位寄存器,隐式零扩展至 64 位)。实际上,对于非指针,系统调用实现无论如何都只会读取低n位,因此您不应该看到任何实际差异,至少对于 32 位值。(例如
SYS_read
,在前 32 位中使用垃圾调用RDI
不会产生错误,并且只考虑低 32 位。)我还没有检查如果您在__X32_SYSCALL_BIT
不清除指针的前 32 位的情况下设置会发生什么。