从C上的x86-64调用NASM时错误的返回值 [英] Wrong return value when calling NASM on x86-64 from C

查看:218
本文介绍了从C上的x86-64调用NASM时错误的返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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屋!

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