2012-03-22 25 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符號的擴展,如果除數爲零,則會發生這種情況。在調用除法之前,您應該明確地檢查除數值,編譯器和處理器都不會這樣做。