我在互联网上发现了这个递归的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
答案 0 :(得分:0)
如果你的呼叫约定正确,那么是的,“它应该有用”。但那些调用约定包括函数的参数。并且可能你想要实际对结果做些什么
查看.recur
以了解如何设置参数(在eax
中),调用函数并获取结果(在堆栈中保留,在本例中为被拉回eax
和edx
)。
然后大概你会想要在退出之前打印出那个结果....
答案 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/