如何在程序集中正确调用函数

时间:2014-01-25 16:55:32

标签: c assembly nasm

我在互联网上发现了这个递归的Fibonacci汇编代码,我试图改进这个,所以结果将打印出来。事情是,如果我添加_main函数并简单地放

call _fibo

在那里,程序将崩溃(更不用说添加更多代码)。我认为调用者必须清理参数,什么不是,但在我看来,如果没有其他代码可以执行,它应该可以工作。有什么指针吗?

_fibo:
push ebp
mov  ebp, esp
sub  esp, 16    ; ...AA-A-A-ND we've built the stack frame

mov  eax, [ebp+8]
cmp  eax, 2
jae  .recur

xor  edx, edx
jmp  .done

.recur:
sub  eax, 2
push eax            ; compute fib(n-2)
call _fibo
mov  [ebp-8], eax   ; save returned value in 8-byte local variable...
mov  [ebp-4], edx   ; ...in Little-Endian byte order.

mov  eax, [ebp+8]   ; get argument again
dec  eax
push eax            ; compute fib(n-1)
call _fibo
mov  [ebp-16], eax  ; save returned value in 8-byte local variable...
mov  [ebp-12], edx  ; ...in Little-Endian byte order.

; the next steps are not as efficient as they could be...
mov  eax, [ebp-8]
mov  edx, [ebp-4]   ; retrieve 1st computed value
add  eax, [ebp-16]
adc  edx, [ebp-12]  ; add 2nd computed value
.done:
mov  esp, ebp
pop  ebp
ret
;----------------------------------------------------------------

http://montcs.bloomu.edu/Code/Asm.and.C/Asm.Nasm/fibonacci.shtml

2 个答案:

答案 0 :(得分:0)

如果你的呼叫约定正确,那么是的,“它应该有用”。但那些调用约定包括函数的参数。并且可能你想要实际对结果做些什么

查看.recur以了解如何设置参数(在eax中),调用函数并获取结果(在堆栈中保留,在本例中为被拉回eaxedx)。

然后大概你会想要在退出之前打印出那个结果....

答案 1 :(得分:0)

最简单的方法是在C中编写main,分别编译两个部分,并将它们链接到一个可执行文件中。这是Linux的一个例子:

#include <stdio.h>

extern long __attribute__((cdecl)) _fibo(int n);

int main()
{
        int number = 10;
        long result = _fibo(number);
        printf("%ld\n", result);
        return 0;
}

注意:从头顶开始,在Windows中,您应该在没有下划线的情况下拨打fibo;并且__attribute__((cdecl))必须是__cdecl

将此行添加到fibo.asm以向_fibo公开main

global _fibo

使用以下命令编译/链接两个模块:

nasm -f elf fibo.asm
gcc main.c fibo.o

如果你坚持在集会中写main,你将不得不了解calling conventions,因为你可能已经从keshlam的答案中猜到了。为了帮助您入门,_fibo使用 cdecl 。您可以在此处找到一些非常有用的代码示例:http://cs.lmu.edu/~ray/notes/nasmexamples/