阶乘程序出现段错误
.section .data
.section .text
.globl _start
_start:
pushl $8 #8入栈 sp=-4
movl $1,%eax #eax=1
call power #调函数 sp=-8
jmp exit
.type power, @function
power:
pushl %ebp #ebp入栈 sp=-12
movl %esp,%ebp #ebp=esp=-12
subl $4,%esp #esp-=4 =-16
movl 8(%ebp),%ebx #ebx=8
cmpl $1,%ebx #if ebx==1
je power_end #跳出
subl 1,%ebx #else : ebx-=1
movl %ebx,-4(%ebp) #-16栈存入7
call power #调函数
movl 12(%esp),%ecx
addl %ecx,%eax
addl $4,%esp
popl %ebp
ret
power_end:
movl $1,%eax
addl $4,%esp
popl %ebp
ret
exit:
movl %eax,%ebx
movl $1,%eax
int $0x80
发现问题, subl 1,%ebx 中的1没有加$符号,加上后解决,得到36.
程序过于复杂,取代ecx为ebx后,加上注释为
.section .data
.section .text
.globl _start
_start:
pushl $8 #8入栈 sp=-4
movl $1,%eax #eax=1
call power #调函数 sp=-8
jmp exit
.type power, @function
power:
pushl %ebp #ebp入栈 sp=-12
movl %esp,%ebp #ebp=esp=-12
subl $4,%esp #esp-=4 =-16
movl 8(%ebp),%ebx #ebx=8
cmpl $1,%ebx #if ebx==1
je power_end #跳出
subl $1,%ebx #else : ebx-=1
movl %ebx,-4(%ebp) #-16栈存入7
call power #调函数
movl 12(%esp),%ebx #从子函数跳出后,sp在dsp的-4位置,0(%esp)保存着子函数阶乘的数,12(%esp)是本阶
乘需要用的数。
addl %ebx,%eax #将本阶段数与递归回来的数相加
addl $4,%esp #esp归位
popl %ebp #弹出ebp
ret #跳出函数,返回值在eax中
power_end:
movl $1,%eax
addl $4,%esp
popl %ebp
ret
exit:
movl %eax,%ebx
movl $1,%eax
int $0x80
迭代计算有误,应该是120,测试结果为14.
.section .data
.section .text
.globl _start
_start:
movl 5,%ecx
pushl %ecx
loop:
cmpl $1, %ecx
je exit
call power
jmp loop
.type power, @function
power:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%ecx
movl 12(%ebp),%eax
decl %ecx
movl %ecx,8(%ebp)
incl %eax
imull 12(%ebp),%eax
mov %eax,12(%ebp)
power_exit:
popl %ebp
ret
exit:
movl %eax,%ebx
addl 1,%eax
int $0x80
更改为如下,解决,设计上应该有一个自增的用于阶乘的参数,加上一个自减的用于计数的参数,再有一个记录前期所有阶乘结果的参数。三个参数都是迭代所需。
14那个结果原因在于上面代码计算出的结果是42*43,结果的二进制是0111 0000 1110 ,ebx带着这个值从程序中返回,但是返回的值需要小于255,也就是只收集一个字节,一个字节只有八个比特位,由于机器是小端的,所以上面的二进制在内存中是0110 0000 1110 按这个顺序读一个字节,恰好是0110 0000 ,cpu读这个内存得到的数其实是 0000 0110,也就是14,所以解决。
.section .data
.section .text
.globl _start
_start:
movl $1,%edx
pushl %edx
movl $5,%ecx
pushl %ecx
movl $1,%eax
pushl %eax
loop:
cmpl $1, %ecx
je exit
call power
jmp loop
.type power, @function
power:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
movl 12(%ebp),%ecx
movl 16(%ebp),%edx
decl %ecx
movl %ecx,12(%ebp)
incl %edx
movl %edx,16(%ebp)
imull %edx,%eax
mov %eax,8(%ebp)
power_exit:
popl %ebp
ret
exit:
movl %eax,%ebx
addl $8,%esp
movl $1,%eax
int $0x80