2014-06-22 46 views
-1

據我所知,當在C函數調用中傳遞參數時,被調用者可以在[ebp+8]處找到第一個參數。
通過eax返回值適用於我,從堆棧讀取正確的參數值不。無法將參數從C傳遞到彙編代碼

現在我只是想編寫一個彙編函數,它可以從C調用並返回相同的值,它正在傳遞。

當我運行以下程序時,它將number: 1打印到控制檯,無論傳入的值是myFunc。我究竟做錯了什麼?


assembly.s

section .text 
    global _myFunc 

    _myFunc: 
     mov eax, [ebp+8] 
     ret 

的main.c

#include <stdio.h> 

extern unsigned int myFunc(unsigned int somedata); 

int main() { 
    unsigned int i = myFunc(6); 
    printf("number: %i\n",i); 
    return 0; 
} 

我使用的是Mac,NASM組裝的C語言編譯代碼和gcc。

的Makefile

macho32: 
    nasm -f macho32 assembly.s 
    gcc -m32 -o macho32 assembly.o main.c 
+1

了我的元素的一點點,但我認爲你必須設置'ebp'與'推ebp'和'MOV EBP,esp'之前你組裝功能你可以引用函數參數。那麼在你返回之前,你需要'pop ebp'。請參閱http://unixwiz.net/techtips/win32-callconv-asm.html –

回答

1

您參考參數堆棧,通過閱讀[EBP +偏移] - 已EBP已成立實際上是在堆棧點?如果沒有,你可能需要做的,首先,由傳統的做法:

push ebp  
mov ebp,esp 

只有那麼點EBP其堆放以前的內容,下方堆疊的返回地址,並通過了以下論據。

+0

並且不要忘記在返回之前「流行ebp」,或者我認爲'leave'可以用作替代品。 –

+0

我認爲,這是C編譯器爲我完成的。非常感謝。 –

+0

歡迎大會:) –

1

您需要設置以首先通過保存esp訪問參數。

http://www.nasm.us/doc/nasmdoc9.html

章節 「9.1.2函數定義和函數調用」

我下面的作品

assembly.s

section .text 
    global myFunc:function 

    myFunc: 
    push ebp 
    mov ebp, esp 
    mov eax, [ebp+8] 
    mov esp, ebp 
    pop ebp 
     ret 

主:這是在解釋.c

#include <stdio.h> 

extern unsigned int myFunc(unsigned int somedata); 

int main() { 
    unsigned int i = myFunc(6); 
    printf("number: %i\n",i); 
    return 0; 
} 

大會&編譯

[email protected]:~$ nasm -f elf32 assembly.s 
[email protected]:~$ gcc -m32 assembly.o main.c 
[email protected]:~$ ./a.out 
number: 6 

我在Linux機器上,所以我用elf32。在您的Mac上使用macho32正確。

+0

'mov esp,ebp'只是爲了抓住任何東西,這是推動,但沒有在我的彙編代碼中,對不對?否則,esp應該和以前一樣處於相同的位置。 –

+0

這樣做的原因在於ESP下方的空間通常用於局部功能變量,並且通過減少ESP所需的空間量來保留 - 隨後,在功能結束時,ESP會恢復到原來的值 –

1

你的功能應該是這樣的,

_myFunc: 

    push ebp     ; setup ebp as frame pointer 
    mov  ebp, esp 

    mov  eax, [ebp + 8] 

    leave       ; mov esp,ebp/pop ebp 

    ret 

的約定是使用EBP訪問的參數,這樣做,你需要保存在棧上EBP並使其指向堆棧的新頂部。在功能出口處,您應該恢復ebp特別提示,因爲離開指令。

NASM有一個宏包,c32.mak,可以在支持C調用約定幫助,這些宏ARGPROCENDPROC。 使用這些宏代碼應該是什麼樣子,

proc _myfunc 
%$i arg 

    mov  eax, [ebp + %$i] 

endproc