【问题标题】:How to call functions properly in assembly如何在汇编中正确调用函数
【发布时间】:2014-01-25 16:55:31
【问题描述】:

我在互联网上找到了这个递归斐波那契汇编代码,我正在尝试改进它,以便将结果打印出来。问题是,如果我添加 _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

【问题讨论】:

  • 只是为了学习它的基础知识,当然它不是用来编写可以拆分成部分的程序
  • 代码在我看来不是'C',你确定它是C语言吗???

标签: c assembly nasm


【解决方案1】:

最简单的方法是用 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/

【讨论】:

  • 我知道cdecl,但显然需要了解更多。谢谢,我会尝试修复它并让你知道我是怎么做的:)
【解决方案2】:

如果调用约定正确,那么是的,“它应该可以工作”。但是那些调用约定包括函数的参数。并且大概你想对结果做一些实际的事情

查看.recur 以了解如何设置参数(在eax 中)、调用函数并获取结果(留在堆栈上,在这种情况下被拉回eaxedx)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    • 2016-09-07
    • 2017-02-18
    • 1970-01-01
    相关资源
    最近更新 更多