使用寄存器而不是堆栈从x64汇编中调用C函数 [英] Calling C function from x64 assembly with registers instead of stack
问题描述
这个答案使我感到困惑.
根据标准C调用约定,这是调用C函数的标准方式是push
堆栈的参数和call
子例程的参数.这与系统调用明显不同,在后者中,您使用适当的参数设置了不同的寄存器,然后
According to the standard C calling conventions, the standard way to call C functions is to push
arguments to the stack and to call
the subroutine. That is clearly different from syscalls, where you set different registers with appropriate arguments and then syscall
.
但是,上面提到的答案给出了此GAS代码:
However, the answer mentioned above gives this GAS code:
.global main
.section .data
hello: .asciz "Hello\n"
.section .text
main:
movq $hello, %rdi
movq $0, %rax
call printf
movq $0, %rax
ret
与gcc hello.s -o hello
一起使用.调用printf
的部分是:
which works with gcc hello.s -o hello
. The part that calls printf
is:
movq $hello, %rdi
movq $0, %rax
call printf
它使用rdi
寄存器而不是堆栈将参数传递给printf
.将以上内容更改为
It is using the rdi
register, not the stack, to pass the argument to printf
. Changing the above to
push $hello
call printf
导致细分错误.
由于printf
是C函数,与sys_write
不同,我认为参数应该传递给堆栈,而不是寄存器.我在这里误会什么?其他标准C函数(例如malloc
)如何?
Since printf
is a C function, unlike sys_write
, I think the arguments should be passed to the stack, not the registers. What am I misunderstanding here? What about other standard C functions, such as malloc
?
(任何参考文献都将不胜感激.)
(Any reference would be truly appreciated.)
推荐答案
将参数传递给可变参数函数更为复杂.请参阅 x86-64 ELF ABI ,第3.5.7节.否则,x86-64将使用以下寄存器传递其前6个参数:%rdi, %rsi, %rdx, %rcx, %r8, %r9
(不包括float/vector参数).
Passing arguments to variadic functions is more complicated. See x86-64 ELF ABI, section 3.5.7. Otherwise, x86-64 passes its first 6 arguments using registers: %rdi, %rsi, %rdx, %rcx, %r8, %r9
(excluding float / vector arguments).
根据规范,%rax = 0
表示变量参数列表没有在向量寄存器中传递的(0)浮点参数.您的方法是错误的,因为必须在%rdi
中传递第一个参数(例如,以nul终止的字符串:"Hello\n"
),并且在调用函数时%rax
必须为零.
From the specification, %rax = 0
means that the variable argument list has no (0) floating-point arguments passed in vector registers. Your approach is wrong, as the first argument (e.g., the nul-terminated string: "Hello\n"
) must be passed in %rdi
, and %rax
must be zero when the function is called.
这篇关于使用寄存器而不是堆栈从x64汇编中调用C函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!