无法将参数从C传递到汇编代码

时间:2014-06-22 13:06:55

标签: c assembly nasm

根据我的理解,当在C中的函数调用中传递参数时,被调用者可以在[ebp+8]找到第一个参数。
通过eax返回值对我有用,从堆栈中读取正确的参数值不会。

现在我只是尝试编写一个汇编函数,可以从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来汇编代码和gcc进行C编译。

生成文件

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

3 个答案:

答案 0 :(得分:1)

你在堆栈上引用参数,通过读取[EBP + offset] - EBP是否设置为实际指向堆栈?如果不是,您可能必须先执行此操作,通常由以下方式完成:

push  ebp    
mov   ebp,esp

然后才将EBP指向其堆叠的先前内容,低于堆叠的返回地址,以及下面传递的参数。

答案 1 :(得分: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

的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;
}

装配&amp;汇编

ericu@eric-phenom-linux:~$ nasm -f elf32 assembly.s 
ericu@eric-phenom-linux:~$ gcc -m32  assembly.o main.c
ericu@eric-phenom-linux:~$ ./a.out 
number: 6

我在linux机器上,所以我使用elf32。在Mac上使用macho32是正确的。

答案 2 :(得分: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 esp ,因为离开指令。

nasm 中有一个宏包 c32.mak ,可以帮助支持 C调用约定,这些宏是< strong> arg , proc endproc 。 使用这些宏,您的代码应该是,

proc _myfunc
%$i arg

    mov     eax, [ebp + %$i]

endproc