Linux
我應該如何將 32 位參數傳遞給 x86_64 上的 Linux 系統呼叫?
如果系統呼叫需要一些 32 位參數,例如
uid_t
或int
(用於文件描述符)unsigned int
甚至一些 16 位類型,我如何使用 64 位寄存器傳遞它們?在使用指令之前,我是否需要將它們零擴展或符號擴展為 64 位
syscall
?如果我
__X32_SYSCALL_BIT
在 RAX 中使用,原來的 64 位指針類型參數變為 32 位,我仍然需要使用相同的 64 位寄存器來傳遞參數,在這種情況下我是否需要對地址參數進行零擴展?
您應該對它們進行零擴展,但是對於 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 位的情況下設置會發生什麼。