我有以下两个功能。 nCr计算int的阶乘。 nCr调用另一个函数,它是进行计算的阶乘。随着数字变大,存在溢出。我需要设置溢出条件。我正在尝试使用JO(跳过溢出),但是在编译时我遇到了问题。大胆是我提出条件的地方。如果有人可以帮助指出我的错误那将是伟大的!
_nCr:
pushl %ebp
movl %esp, %ebp
subl $56, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
**
call _factorial cmp $0, %eax je L22 cmpl $0, %eax jne L23 L22: movl $0, %eax leave ret
**
L23:
movl %eax, -12(%ebp)
movl 12(%ebp), %eax
addl $1, %eax
movl %eax, (%esp)
call _factorial
movl %eax, -16(%ebp)
movl 12(%ebp), %eax
notl %eax
addl 8(%ebp), %eax
movl %eax, (%esp)
call _factorial
movl %eax, -20(%ebp)
movl -16(%ebp), %eax
movl %eax, %edx
imull -20(%ebp), %edx
movl %edx, -28(%ebp)
movl -12(%ebp), %eax
movl %eax, %edx
sarl $31, %edx
idivl -28(%ebp)
leave
ret
_factorial:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl $1, -8(%ebp)
movl $1, -4(%ebp)
jmp L3
L4:
movl -8(%ebp), %eax
**
imull -4(%ebp),%eax
jo L2
**
movl %eax, -8(%ebp)
addl $1, -4(%ebp)
L2:
movl $0, %eax
leave
ret**
L3:
movl -4(%ebp), %eax
cmpl 8(%ebp), %eax
jle L4
movl -8(%ebp), %eax
leave
ret
基本上如果检测到溢出,则函数应返回0.
答案 0 :(得分:0)
首先,如果您的值被限制为32位,则使用循环进行阶乘是很奇怪的,因为阶乘(12)是最后一个适合32位的值。因此,将factorial实现为表查找1到12之间的值更简单,并为任何其他值返回0。
如果您仍然想要使用循环(好吧,它可以是作业要求),请注意放在%edx中的产品的大部分(通过imull)。它应等于%eax符号的扩展,否则产品不能适合32位。两个示例变体:
mov %eax, %ecx
sarl $31, $ecx
cmp %edx, %ecx
jne overflow_found
或
mov %edx, %ecx
cltd
cmp %edx, %ecx
jne overflow_found
我也很困惑你的程序数字溢出的地方。唯一可疑的地方是“idiv”,但只要%edx是%eax符号的扩展,如果除数为零,就会发生这种情况。你应该在调用divide之前显式检查divisor值,编译器和处理器都不会这样做。