我正在学习汇编,我有这个函数,其中包含一些我不明白的行:
. 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 );
}
我不确定标有数字的行。
pushl %eax
:是不是意味着我们把%eax
的内容放到%esp
?所以我们调用
factR()
。当我们返回这里执行下一条指令时,结果会在%esp
中吗?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/