使用寄存器而不是堆栈从x64汇编中调用C函数 [英] Calling C function from x64 assembly with registers instead of stack

查看:165
本文介绍了使用寄存器而不是堆栈从x64汇编中调用C函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个答案使我感到困惑.

根据标准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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆