【发布时间】:2015-04-20 12:06:59
【问题描述】:
This answer 让我很困惑。
根据standard C calling conventions,调用C 函数的标准方法是将push 参数传递给堆栈和call 子例程。这与syscalls 明显不同,在syscalls 中,您使用适当的参数设置不同的寄存器,然后syscall。
但是,上面提到的答案给出了这个 GAS 代码:
.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的部分是:
movq $hello, %rdi
movq $0, %rax
call printf
它使用rdi 寄存器而不是堆栈将参数传递给printf。将上述更改为
push $hello
call printf
导致分段错误。
由于printf 是一个C 函数,与sys_write 不同,我认为应该将参数传递给堆栈,而不是寄存器。我在这里有什么误解?其他标准 C 函数呢,比如malloc?
(任何参考将不胜感激。)
【问题讨论】:
-
“约定”不是“标准”。在 64 位世界中情况有所不同。看看this Wikipedia article。
标签: assembly x86-64 calling-convention gnu-assembler