【问题标题】:Understanding assembly recursive function理解汇编递归函数
【发布时间】:2011-12-29 08:55:09
【问题描述】:

我正在学习汇编,我有这个函数,其中包含一些我不明白的行:

. globl
. text

factR:
 cmpl $0 ,4(% esp )
 jne cont
 movl $1 ,%eax
 ret

cont :
 movl 4(%esp),%eax
 decl %eax
 pushl %eax          // (1)
 call factR          // (2)
 addl $4,%esp        // (3)
 imull 4(%esp),%eax 
 ret

对应的C代码是:

int factR ( int n ) {
    if ( n != 0 )
        return n;
    else
        return n ∗ factR ( n − 1 );
}

我不确定标有数字的行。

  1. pushl %eax: 是不是说我们把%eax的内容放进去 %esp?

  2. 所以我们调用factR()。当我们回到下一个指令时,结果会在%esp 中吗?

  3. addl $4,%esp 不确定这个,我们是在存储在%esp 中的数字上加 4 还是在指针上加 4 以获得下一个数字或类似的东西?

    李>

【问题讨论】:

  • C 代码应为if ( n == 1 ) return 1; else return n ∗ factR ( n − 1 ); 以等效于汇编代码。 (另外,这是阶乘的正确实现)

标签: c assembly intel factorial i386


【解决方案1】:

factR() 函数似乎遵循 C 调用约定 (cdecl)。这是 caller 将函数调用的参数推送到堆栈上的地方,caller 清理堆栈(撤消对执行该函数的堆栈所做的更改call) 当函数返回时。

第一次推送 (1) 将 %eax 寄存器的内容作为参数放入以下调用。然后对函数进行实际调用 (2)。然后通过将堆栈指针%esp 重置为在步骤 1 中没有将参数推回的状态来清理堆栈 (3)。它推入了一个 32 位值,因此它必须将指针调整 4-字节。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-31
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    相关资源
    最近更新 更多