[英]Wrong return value when calling NASM on x86-64 from C
I'm studying NASM on Linux 64-bit and have been trying to implement some examples of code.我正在 Linux 64 位上学习 NASM,并且一直在尝试实现一些代码示例。 However I got a problem in the following example.
但是,我在以下示例中遇到了问题。 The function donothing is implemented in NASM and is supposed to be called in a program implemented in C:
函数 donothing 是在 NASM 中实现的,应该在一个用 C 实现的程序中调用:
File main.c:文件 main.c:
#include <stdio.h>
#include <stdlib.h>
int donothing(int, int);
int main() {
printf(" == %d\n", donothing(1, 2));
return 0;
}
File first.asm文件优先.asm
global donothing
section .text
donothing:
push rbp
mov rbp, rsp
mov eax, [rbp-0x4]
pop rbp
ret
What donothing does is nothing more than returning the value of the first parameter. donothing 所做的无非是返回第一个参数的值。 But when donothing is called the value 0 is printed instead of 1. I tried rbp+0x4, but it doesn't work too.
但是当调用 donothing 时,打印的值是 0 而不是 1。我试过 rbp+0x4,但它也不起作用。 I compile the files using the following command:
我使用以下命令编译文件:
nasm -f elf64 first.asm && gcc first.o main.c
Compiling the function 'test' in C by using gcc -s the assembly code generated to get the parameters looks similar to the donothing:使用 gcc -s 在 C 中编译函数 'test' 为获取参数而生成的汇编代码看起来类似于 donothing:
int test(int a, int b) {
return a > b;
}
Assembly generated by gcc for the function 'test' above: 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
So, what's wrong with donothing?那么,什么都不做有什么错呢?
In x86-64 calling conventions the first few parameters are passed in registers rather than on the stack.在x86-64 调用约定中,前几个参数在寄存器中而不是在堆栈中传递。 In your case you should find the
1
and 2
in RDI
and RSI
.在您的情况下,您应该在
RDI
和RSI
找到1
和2
。
As you can see in the compiled C code, it takes a
from edi
and b
from esi
(although it goes through an unnecessary intermediate step by placing them in memory)正如您在编译后的 C 代码中所见,它从
edi
获取a
并从esi
获取b
(尽管它通过将它们放入内存而经历了一个不必要的中间步骤)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.