c - 理解汇编递归函数

标签 c assembly intel factorial i386

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

. 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 不确定这个,我们是将 4 加到存储在 %esp 中的数字还是将 4 加到指针获取下一个数字或类似的东西?

最佳答案

factR() 函数似乎遵循 C 调用约定 (cdecl)。 caller 将函数调用的参数压入堆栈,caller 清理堆栈(撤消执行函数时对堆栈所做的更改)函数返回时调用)。

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

关于c - 理解汇编递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8665718/

相关文章:

c - 分配/取消分配资源

c - setuid() 失败 - 不允许操作

c - 有没有跨平台的小型\可移植C图像编辑库?

c++ - 程序集,全局变量

assembly - 访问程序集 X64 函数中的结构字段

performance - x86 bsr/bsf 如何具有固定延迟,而不依赖于数据?它不是像伪代码显示的那样循环遍历位吗?

c - 对 argv 中的参数使用条件

c - 指令级的有符号数模数

c - 启用/禁用硬件锁省略

intel - 为什么两者都有? vperm2f128 (avx) 与 vperm2i128 (avx2)