2015-01-11 90 views
1

我有這個代碼(having a string of length n, build another of length n-2 as it follows: sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3),我不知道它爲什麼凍結。沒有錯誤,我已經調試了一段時間,但我無法弄清楚問題是否與算法有關。x86程序凍結[tasm]

prints macro number 
local decompose, pops 
    mov bx,10 
    mov al, number 
    mov cx,0 
    decompose: ;pushing digits to the stack 
     inc cx 
     mov ah,0 
     div bl 
     mov dl,ah ; remainder - last digit 
     add dx,48 ; to transform it in its char version 
     push dx 
     cmp al,0 
     jnz decompose 
    pops:    ; pop digits off the stack 
     pop dx 
     mov ah,2h 
     int 21h 
    loop pops 
     ; pretty spacing 
     mov dl,' ' 
     mov ah,2h 
     int 21h 

endm 

data segment para public 'data' 
    sir db 5, 10, 12, 4, 3 
    n equ $-sir 
    sir2 db n-2 dup(0) 
data ends 

code segment para public 'code' 
start proc far 
    assume cs:code,ds:data 
    push ds 
    xor ax,ax 
    push ax 
    mov ax,data 
    mov ds,ax 

    mov si,0 
    mov dx,3 
    mov cx,n 
    sub cx,2 

l1: 
    mov ah,0 
    mov al,sir[si] 
    add al,sir[si+1] 
    add al,sir[si+2] ;sum of 3 numbers 
    div dx     ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3 
    mov sir2[si],al 
    inc si 
    cmp si,cx 
jbe l1 

    mov si,0 
l2: 
    prints sir2[si] 
    inc si 
loop l2 

ret 
start endp 
code ends 
end start 

任何人都可以幫忙嗎?

+1

你做了什麼努力來發現它爲什麼會凍結,你卡在哪裏?換句話說,**你是否調試過你的代碼**?這個網站不是一個免費的調試服務,因此,就你的問題而言,最有可能的是,它會脫離主題。 –

+0

是的,我做了+我以爲我被困在一個循環,所以我改變它爲一個jmp。 –

+1

您在* decompose *例程中清除了CX!將'mov cx,0'改成'mov ah,0' –

回答

1

變化

div dx     ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3 

div dl     ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3 

(見邁克爾的答案)。

宏是一段代碼,它在調用宏的地方按原樣插入。宏prints更改CX,您需要保持loop l2不變。重寫循環:

mov si, 0 
    mov di, cx 
l2: 
    prints sir2[si] 
    inc si 
    dec di 
    jnz l2 

BTW:不要忘記定義堆棧:

_STACK SEGMENT PARA STACK 'STACK' 
    dw 1024 dup (?) 
_STACK ENDS 
+0

它允許寫'cmp si,n-2'嗎? –

+0

@LorenaSfăt:是的。 TASM在編譯時將'n-2'轉換爲一個常數。 – rkhb

+0

好,所以現在我想它一定是算法,因爲它打印一些值(不正確的),然後它凍結... –

1

DIV r/m16的描述爲「Unsigned divide DX:AX by r/m16。換句話說,分子是由組合的DXAX中的位形成的32位值。
如果商數變得太大而不適合AX,則會發生異常。爲了避免這種情況,您應該在劃分之前清除DX(即mov dx,0xor dx,dx)。顯然這也意味着你不能使用DX作爲分母。

1

你的程序可能會凍結,因爲你正在做一個迭代太多了!

cmp si,cx 
jbe l1 

這給了4次迭代,而SIR2只有3個字節的存儲空間!使用jb l1

+0

我希望就是這樣。我做了你們所有人都說的,現在它打印價值(不是正確的),然後它凍結。 –

+0

我希望這個程序只用'ret'退出,那麼你應該刪除'push ds'和'push ax'指令。或者使用'mov ah,4Ch'和'int 21h'作爲程序的最後一步。 –

+0

但是老師說這是.exe程序主體的一部分,我們應該照原樣使用它:/ –