从C调用x86-64上的NASM时返回值错误

我在Linux 64位上学习NASM,并且一直在尝试实现一些代码示例。 但是我在下面的示例中遇到了问题。 函数donothing在NASM中实现,并且应该在用C实现的程序中调用:

文件main.c:

#include  #include  int donothing(int, int); int main() { printf(" == %d\n", donothing(1, 2)); return 0; } 

提交first.asm

 global donothing section .text donothing: push rbp mov rbp, rsp mov eax, [rbp-0x4] pop rbp ret 

什么不做只不过是返回第一个参数的值。 但是当调用donothing时,将打印值0而不是1.我尝试了rpb + 0x4,但它也不起作用。 我使用以下命令编译文件:

  nasm -f elf64 first.asm && gcc first.o main.c 

使用gcc -s在C中编译函数’test’,生成的汇编代码用于获取参数类似于donothing:

 int test(int a, int b) { return a > b; } 

由gcc为上面的函数’test’生成的汇编:

 test: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl %edi, -4(%rbp) movl %esi, -8(%rbp) movl -4(%rbp), %eax cmpl -8(%rbp), %eax setg %al movzbl %al, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc 

那么,什么是不好的?

在x86-64调用约定中 ,前几个参数在寄存器中而不是在堆栈中传递。 在您的情况下,您应该在RDIRSI找到12

正如您在编译的C代码中看到的那样,它从esi获取a edib (尽管它通过将它们放在内存中进行了不必要的中间步骤)