Assembly 如何在汇编语言X86中设置溢出条件
我有以下两个功能。nCr计算整数的阶乘。nCr调用另一个阶乘函数进行计算。随着数字越来越大,出现了溢出。我需要设置溢出条件。我试图使用JO(溢出跳转),但编译时遇到了问题。我把我的条件放在粗体上。我的错在哪里Assembly 如何在汇编语言X86中设置溢出条件,assembly,x86,Assembly,X86,我有以下两个功能。nCr计算整数的阶乘。nCr调用另一个阶乘函数进行计算。随着数字越来越大,出现了溢出。我需要设置溢出条件。我试图使用JO(溢出跳转),但编译时遇到了问题。我把我的条件放在粗体上。我的错在哪里 _nCr: pushl %ebp movl %esp, %ebp subl $56, %esp movl 8(%ebp), %eax movl %eax, (%esp) ** **
_nCr:
pushl %ebp
movl %esp, %ebp
subl $56, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
**
**
**
imull-4(%ebp),%eaxjo L2 **
基本上,如果检测到溢出,那么函数应该返回0。首先,如果您的值被限制为32位,那么对阶乘使用cycle是很奇怪的,因为阶乘(12)是最后一个适合32位的值。因此,对于介于1和12之间的值,实现阶乘作为表查找更简单,对于任何其他值,都返回0 如果您仍然想使用cycle(嗯,这可能是家庭作业要求),请注意产品的较高部分(按imull),它位于%edx中。它应等于%eax符号的扩展,否则产品不能放入32位。这方面的两个示例变体:
mov %eax, %ecx
sarl $31, $ecx
cmp %edx, %ecx
jne overflow_found
或
我也很困惑你的程序在哪里会出现数字溢出。唯一可疑的地方是“idiv”,但只要%edx是%eax符号的扩展,如果除数为零,就会发生这种情况。在调用divide之前,您应该显式检查除数值,编译器和处理器都不会这样做。我看不到任何粗体的可能重复项。您能更具体地说明编译时遇到的问题吗?我将各个部分分开,并使用**。第一个块在第一次调用阶乘之后,第二个块在整数相乘时。我遇到的问题是“浮点异常(内核转储)。当我试图修改它时,我的程序将无法工作。溢出将发生在13!但如果我输入的int为2
imul
则不会运行。这发生在idiv
指令中。
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
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
mov %eax, %ecx
sarl $31, $ecx
cmp %edx, %ecx
jne overflow_found
mov %edx, %ecx
cltd
cmp %edx, %ecx
jne overflow_found