2012-12-01 57 views
3

我已經用匯編語言(MASM)編寫了一個程序,允許學生練習計算組合。該程序遞歸計算階乘。我使用一個叫做組合的過程,它接收n和r,然後得到(n = r)!, n !, r!通過調用稱爲階乘的過程。因子是遞歸的。未處理的異常:彙編中的遞歸階乘(MASM)

.data 
n  DWORD ? 
r  DWORD ? 
result DWORD ? 
answer   DWORD ? 
divisor DWORD ? 

.code 
MAIN PROC 

(一些初步的過程調用)

push OFFSET divisor  ;ebp+20 
push n    ;ebp+16 
push r    ;ebp+12 
push OFFSET result  ;ebp+8 
call combinations 

;************************************************* 
; combinations calls factorial (3 times) to calculate n!, r!, and (n-r)!. 
; combinations calculates n!/(r!(n-r)!) , and stores the value in result. 
; receives: accepts n and r by value and result by address. 
; returns: none 
; preconditions: none 
; registers changed: eax, ebx, edx 
;************************************************* 
combinations PROC 
push  ebp 
mov  ebp,esp 

mov  eax, [ebp+16] ;find (n-r)! 
sub  eax, [ebp+12] 
mov  ebx, eax 
push  ebx 
call  factorial 
pop  ebx 
mov  edx,[ebp+20] ;move (n-r)! into result 
mov  [edx],eax 

mov  ebx, [ebp+12]  ;find r! 
push  ebx 
call  factorial 
pop  ebx 

mov  edx,[ebp+20] 
mov  ebx, [edx] 
mul  ebx   ;r!*(n-r)!, store product in eax 
mov  ebx, [ebp+20] 
mov  [ebx], eax   ;store product in divisor variable 

mov  ebx, [ebp+16] ;find n! 
push  ebx 
call  factorial 
pop  ebx 
mov  edx,[ebp+20]    
mov  ebx,[edx]   ;move value of divisor into ebx 

mov  edx, 0 
div  ebx   ;divide n! by divisor (r!*(n-r)!) 
mov  ebx, [ebp+8] 
mov  [ebx],eax     ;move quotient into result 

pop  ebp 
ret  16 
combinations ENDP 

;************************************************* 
; calculates factorial recursively 
; receives: 
; returns: factorial solution in eax 
; preconditions: none 
; registers changed: eax 
;************************************************* 
factorial PROC 
mov eax,dword ptr [esp+4] 
cmp eax,1 
jle endRecursive 
dec eax 
push eax 
call factorial 
mov esi,dword ptr [esp+4] 
mul esi 
endRecursive: 
    ret 4 
factorial ENDP 

一切如預期,我得到所需要的值。然而,當所有計算完成並且程序在組合過程結束時達到語句「ret 16」時,我會得到以下例外:

Project.exe中0x76f915de處未處理的異常:0xC0000005:訪問衝突。

我已經運行它通過調試器,並試圖改變返回語句,如果我失算,但我迄今爲止沒有嘗試過的任何工作。也許這是一個盯着這個太長時間的情況,但任何想法將不勝感激。提前致謝。

更新:只是跟蹤EBP和ESP在調試器:它看起來像當程序出來的最後階乘調用的,尤其是EBP的+12,所以它的加入+4用階乘每次調用。因此,當程序碰到pop ebp時,ebp指向r而不是它應該在的位置。有關如何解決這個問題的任何建議?

回答

3

您需要刪除在三個頂級調用factorial之後出現的三條pop ebx指令。由於factorial已將其參數從堆棧中彈出(通過使用ret 4),試圖通過執行pop ebx再次移除參數,從而使堆棧指針變混亂。

+0

這個伎倆!謝謝! – user1852050