1

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

文件 main.c:

#include <stdio.h>
#include <stdlib.h>

int donothing(int, int);

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

文件优先.asm

global donothing

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

donthing 所做的无非是返回第一个参数的值。但是当调用 donthing 时,打印值 0 而不是 1。我尝试了 rbp+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

那么,什么都不做有什么问题呢?

4

1 回答 1

4

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

正如您在编译的 C 代码中看到的那样,它aedibesi(尽管它通过将它们放入内存中经历了不必要的中间步骤)

于 2013-06-19T15:04:51.377 回答