2013-05-03 110 views
2

您好,這是我第一次在這裏發佈,但我正在做一個家庭作業的任務是設計一個裝配函數syracuse(N,序列)與這些給定的規則: 1。如果N是1,則結束循環。 2.如果N是偶數,則N = N/2,循環的開始時轉到3. 如果N是奇數,則N = 3N + 1,循環的開始時轉到x86彙編程序崩潰,可能忽略簡單的錯誤

很簡單,那麼他要我們顯示一些信息並創建報告。但是,我一直盯着這個代碼幾個小時,現在我無法弄清楚什麼是錯的。一旦我註釋掉了這個調用,該程序就能很好地工作,不會崩潰,否則會崩潰。我想我只是忽略了一些簡單而基本的東西,你們中的任何一個人可以提供幫助嗎?

下面是代碼:

.586 
.MODEL FLAT 
INCLUDE io.h 
cr EQU 0dh;carriage return 
Lf EQU 0ah;line feed 
.STACK 4096 
.DATA 
array DWORD ? 
n  DWORD 0 
steps DWORD 0 
prompt BYTE "Enter N: ", 0 
count BYTE cr, Lf, "Total Numbers: " 
string BYTE 40 DUP (?) 
result BYTE cr, Lf, "N: " 

;result2 BYTE cr, Lf, "Steps: " 
lbl BYTE 11 DUP (?) 
BYTE cr, Lf, 0 
.CODE 
_start PROC 
    output prompt ;ask for n 
    input string, 40 
    atod string ; convert to int 
    mov n, eax 
    dtoa lbl, n ;convert to ascii 
    output result; print out n 

    push n 
    push array 
    call syracuse 
    add esp, 8 
    ret 
_start ENDP 
syracuse PROC ; syracuse(n, array) 
    push ebp 
    mov ebp, esp 
    push ebx;save ebx 
    push eax;save eax 
    push esi 
    mov eax, [ebp+8] ;first parameter 
    lea esi, [ebp+12] ;beginning of the array 
      mov ecx, 0 
    whileLoop: inc ecx; ecx++ 
       mov [esi+4], eax 
       cmp eax, 1 
       je endLoop ;if n = 1, then end 
       mov ebx, 2 
       idiv ebx 
       cmp edx, 0 
       je evenProc ; if n is even 

       ;if n is odd then 3N + 1 
       shl eax, 1 
       add eax, 2 
       jmp whileLoop    
    evenProc: ;if n is even then N = N/2 
     mov ebx, 2 
     idiv eax 
     jmp whileLoop 
    endLoop: 
     dtoa lbl, ecx 
     output count;display count 
     pop esi 
     pop eax 
     pop ebx 
     pop ebp 
     ret 

syracuse ENDP 
END 

回答

2

最好的辦法是通過你的組件使用調試器和步進。但是,有一些東西跳到我身上:

array不是數組,它只是一個未初始化的DWORD。

push n 
push array 

這是基於syracuse如何訪問其參數而倒退的。通常,您的調用約定將按推送順序從右到左。如果數組首先被推入,它的值將在EBP + 12,n將在EBP + 8。

mov [esi+4], eax 

ESI = EBP + 12。因此,[ESI + 4] = [EBP + 16],堆棧位置可能會存儲start的調用者的返回地址;可能不是一個好主意來改變它。由於array不是真正的數組,並且您每次都寫入相同位置,所以您可能完全跳過使用ESI並使用mov [ebp+12], eax代替(儘管您似乎完全丟棄了該值;也許您想要將地址array)?)。

idiv ebx 

在這種情況下,idiv指令將64位整數EDX:EAX除以操作數EBX。既然你沒有清除EDX,你可能得不到你想要的結果(包括整數溢出異常)。在idiv之前嘗試xor edx, edx

我沒有真正檢查是否所有的邏輯是正確的,只是看到了上述問題。

+0

真棒你解決了我的崩潰問題!非常感謝你的幫助,而不是抨擊我犯了愚蠢的錯誤! – 2013-05-04 03:51:32

+0

我很高興它有幫助。 – 2013-05-04 07:13:30

+1

@JamesLittle如果答案解決了你的問題,確保你接受它! – Aaron 2013-05-06 15:21:57