2012-03-22 37 views
0

我有以下两个功能。 nCr计算int的阶乘。 nCr调用另一个作为计算的因子的函数。随着数字变大,出现溢出。我需要设置溢出条件。我试图使用JO(跳过溢出),但我编译时遇到问题。大胆的地方是我放置自己的条件。如果有人能帮助指出我的错误,那将是非常棒的!如何设置装配语言中的溢出条件X86

_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中
裘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

[如何检测Assembly Langauge X86中的溢出条件]可能的重复(http://stackoverflow.com/questions/9797473/how-to-detect-overflow-conditions-in-assembly-langauge-x86) – 2012-03-22 01:45:14

+0

I没有看到任何粗体。你可以更具体地了解你编译时遇到的问题吗? – 2012-03-22 01:47:10

+0

我分开的部分和使用**。第一个块在第一次调用阶乘之后,第二个块是整数相乘的时间。我得到的问题是“浮点异常(核心转储)”,当我尝试改变它时,我的程序将无法工作,溢出将发生在13!但是如果int I算出是2 – user1282285 2012-03-22 01:56:42

回答

0

首先,如果您的值被限制在32位,它的怪异使用因为阶乘(12)是适合32位的最后一个值。因此,对于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符号的扩展,如果除数为零,则会发生这种情况。在调用除法之前,您应该明确地检查除数值,编译器和处理器都不会这样做。