我有这个汇编代码(使用gcc -m32编译的Linux 32Bit),我真的不明白为什么我的程序不起作用。
.data
.bla:
.ascii "%d\n\0"
.globl main
.text
main: pushl $4
call factorial
movl $1, %eax
ret
factorial:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
cmpl $1, %ecx
jg .rek
movl $1, %eax
movl %ebp, %esp
pop %ebp
ret
.rek:
decl %ecx
pushl %ecx
call factorial
addl $4, %esp
movl 8(%ebp), %ecx
imull %ecx, %eax
pushl %eax
pushl $.bla
call printf
addl $8, %esp
movl %ebp, %esp
pop %ebp
ret
不幸的是,每次发生分段错误+大于4的参数都不起作用。
当我用“3”运行程序时,这应该是我的堆栈:
3
ret add
ebp
2
ret add
ebp
1
ret add
ebp
当我到达递归的底部时,我将保存在eax中的返回值乘以8(%ebp),这应该是下一个值。
我非常感谢您提供的任何帮助。
答案 0 :(得分:2)
我看到的三个问题。
1)您的call maine
(我假设这是一个拼写错误,您的意思是main
)应为call factorial
2)在main
程序中,您无法恢复堆栈指针。
3)您的printf
来电会修改%eax
并覆盖factorial
之前的结果。
修复计划:
.data
.bla:
.ascii "%d\n\0"
.globl main
.text
main: pushl $5
call factorial
addl $4, %esp # ADDED THIS
movl $1, %eax
ret
factorial:
push %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
cmpl $1, %ecx
jg .rek
movl $1, %eax
movl %ebp, %esp
pop %ebp
ret
.rek:
decl %ecx
pushl %ecx
call factorial # FIXED THIS
addl $4, %esp
movl 8(%ebp), %ecx
imull %ecx, %eax
pushl %eax # ADDED THIS - SAVE RETURN VALUE
pushl %eax
pushl $.bla
call printf
addl $8, %esp # MODIFIED THIS
pop %eax # ADDED THIS (restore eax result)
movl %ebp, %esp
pop %ebp
ret