所以我试图在汇编程序中创建一个阶乘函数
在c:
#include<stdio.h>
int fat (int n)
{
if (n==0) return 1;
else return n*fat(n-1);
}
int main (void){
printf("%d\n", fat(4));
return 0;
}
在汇编中:
.text
.global fat
fat:push %ebp
mov %esp, %ebp
movl $1,%eax
movl 4(%ebp),%edx
LOOP:cmp $0,%edx
je FIM
sub $1,%edx
push %edx
call fat
imul %edx,%eax
FIM:mov %ebp, %esp
pop %ebp
ret
我一直得到分段错误错误,我不知道为什么......有人可以帮助我吗?
答案 0 :(得分:2)
这一行的偏移可能是错误的:
movl 4(%ebp),%edx
堆栈的前一个值为%ebp
且返回地址已经存在,因此您的偏移量必须大于4。
我建议使用调试器逐步调试汇编代码,并确保所有寄存器值都与您期望的完全相同。除非您保存并恢复其值,否则您在调用%edx
注册时也会遇到问题。
答案 1 :(得分:1)
fat:push %ebp
mov %esp, %ebp
movl $1,%eax
movl 4(%ebp),%edx /* Must be 8(%ebp) because of the return address! */
LOOP:cmp $0,%edx
je FIM
sub $1,%edx
push %edx
call fat /* The call to fat() just trashed edx, oops. Gotta save/restore it! */
imul %edx,%eax /* The result will be in edx, but you need to return it in eax! */
/* Why isn't "push %edx" compensated here with "pop" or "addl $4,%esp"??? */
FIM:mov %ebp, %esp
pop %ebp
ret
重写你的C函数,装配风格可能会有所帮助:
int fat (int n)
{
int eax, edx, savedEdx;
eax = 1;
edx = n; /* n = %8(%ebp) */
if (edx == 0)
goto done;
savedEdx = edx; /* can do this with pushl %edx */
--edx;
eax = fat(edx); /* pushl %edx; call fat; addl $4, %esp or popl %edx */
edx = savedEdx; /* popl %edx */
eax *= edx; /* can do this with imul %edx */
done:
return eax;
}