为什么 64 位寻址中的 sys_write 调用与用于 32 位寻址的寄存器中的 args 一起工作正常
Why does the sys_write call in 64-bit addressing work fine with args in registers intended to 32-bit addressing
这是一段代码,给我带来了问题:
mystr:
.string "ABCDEFGH"
.set mystrlen, . - mystr
.text
.globl main
.type main, @function
main:
sub [=11=]x10, %rsp
movq [=11=]x44434241, 0x8(%rsp)
lea 0x8(%rsp), %rcx
movq , %rax
movq , %rbx
//movq $mystr, %rcx
//movq $mystrlen, %rdx
movq , %rdx
int [=11=]x80
movq , %rax
movq [=11=], %rbx
int [=11=]x80
表示的片段不起作用,因为在 64 位寻址时,系统调用参数的寄存器应该分别 rdi, rsi, rdx
到第一个、第二个和第三个系统调用参数,而不是 rbx, rcx, rdx
(至于调用 x86-32)。
但我感兴趣的是,为什么注释掉的行可以与 rbx, rcx, rdx
?
一起正常工作
int [=10=]x80
是 32 位兼容接口,它恰好也适用于 64 位进程。它当然使用 32 位约定,这就是您的代码有效的原因。请注意,它仅使用寄存器的低 32 位,您很幸运您的字符串位于低内存中。对堆栈上的字符串进行同样的尝试,该字符串通常在 32 位范围之外,需要 64 位寄存器,因此需要 64 位约定。
这是一段代码,给我带来了问题:
mystr:
.string "ABCDEFGH"
.set mystrlen, . - mystr
.text
.globl main
.type main, @function
main:
sub [=11=]x10, %rsp
movq [=11=]x44434241, 0x8(%rsp)
lea 0x8(%rsp), %rcx
movq , %rax
movq , %rbx
//movq $mystr, %rcx
//movq $mystrlen, %rdx
movq , %rdx
int [=11=]x80
movq , %rax
movq [=11=], %rbx
int [=11=]x80
表示的片段不起作用,因为在 64 位寻址时,系统调用参数的寄存器应该分别 rdi, rsi, rdx
到第一个、第二个和第三个系统调用参数,而不是 rbx, rcx, rdx
(至于调用 x86-32)。
但我感兴趣的是,为什么注释掉的行可以与 rbx, rcx, rdx
?
int [=10=]x80
是 32 位兼容接口,它恰好也适用于 64 位进程。它当然使用 32 位约定,这就是您的代码有效的原因。请注意,它仅使用寄存器的低 32 位,您很幸运您的字符串位于低内存中。对堆栈上的字符串进行同样的尝试,该字符串通常在 32 位范围之外,需要 64 位寄存器,因此需要 64 位约定。