从C上的x86-64调用NASM时错误的返回值 [英] Wrong return value when calling NASM on x86-64 from C
问题描述
我在Linux上的64位研究NASM,并一直试图实现code的一些例子。但是我在下面的例子中的一个问题。该功能donothing在NASM实施,应该在用C语言实现的程序被称为:
main.c文件:
的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;INT donothing(INT,INT);诠释主(){
的printf(==%d个\\ N,donothing(1,2));
返回0;
}
文件first.asm
全球donothing.text段
没做什么:
推RBP
MOV RBP,RSP
MOV EAX,[RBP-位于0x4]
流行RBP
RET
什么donothing做无非是返回的第一个参数的值更。但donothing被调用时的值0被打印,而不是1。我试图RPB +为0x4,但它并没有工作过。
我编译使用以下命令文件:
NASM -f ELF64 first.asm&放大器;&安培; GCC first.o的main.c
通过gcc编译在C函数测试-s生成得到的参数集code看起来类似于donothing:
INT测试(INT A,INT B){
返回> b:
}
大会由海湾合作委员会的作用上述测试产生
测试:
.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%人
movzbl%人,EAX%
popq%RBP
.cfi_def_cfa 7,8
RET
.cfi_endproc
那么,什么是错donothing?
在 X86-64调用约定的前几个参数在寄存器中,而不是在栈上传递。在你的情况,你应该找到 1
和 2
在 RDI
和 RSI
。
正如你可以在编译的C code看到的,它需要 A
从 EDI
和 b
从 ESI
(虽然要经历一个不必要的中间步骤将它们放置在内存中)
I'm studying NASM on Linux 64-bit and have been trying to implement some examples of code. 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:
File 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
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. But when donothing is called the value 0 is printed instead of 1. I tried rpb+0x4, but it doesn't work too. 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:
int test(int a, int b) {
return a > b;
}
Assembly generated by gcc for the function 'test' above:
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. In your case you should find the 1
and 2
in RDI
and RSI
.
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上的x86-64调用NASM时错误的返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!