2013-06-19 26 views
2

我正在學習Linux 64位上的NASM並試圖實現一些代碼示例。但是,我在下面的例子中遇到了問題。該功能donothing在NASM實現,​​應該在C++實現的程序被稱爲:當從x86-64調用NASM上的錯誤返回值時從C

main.c文件:

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

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編譯C中的函數「測試」 -s生成,以獲得參數的彙編代碼看起來類似於donothing:

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

大會通過的GCC功能「測試」上面生成:

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 

那麼,什麼是錯donothing?

+0

更通用的哪些調用約定的問題: http://stackoverflow.com/questions/8691792/how-to-write-assembly-language-hello-world-program-for-64-bit-mac-os-x-using-pri?lq=1 –

回答

4

x86-64 calling conventions前幾個參數傳遞到寄存器而不是在堆棧上。在你的情況下,你應該在RDIRSI找到12

正如你可以在編譯的C代碼中看到,它從ediabesi(雖然要經歷一個不必要的中間步驟,通過將其放置在內存中)

+0

我打賭用'-O'編譯將刪除那些不必要的內存引用。 ;-) –