2011-01-10 39 views
2

我們有一個字符串,它的偏移量在di中。這個proc會將它轉換爲ax中的整數。 該proc將適用於0-999。但例如對於1000或2343或其他大於1000的數字將不起作用。哪裏有問題 ?我很困惑。 tlen也是我定義的臨時字節。程序集atoi暈眩錯誤

atoi proc far 
    mov cl,len 
    mov ch,0 
    mov ah,0 
start: 
    dec cl 
    jcxz addlastdigit 
    mov tlen,cl;save cl 
    mov al,1 
    mov bl,10 
    getMultiplier: 
    mul bl 
    Loop getMultiplier 
    mov cl,tlen ; retrive cl 
    mov dl,byte ptr[di] 
    sub dl,30h 
    mul dl 
    add num,ax 
    inc di 
    jmp start 
addlastdigit: 
    mov ax,num 
    mov dl,byte ptr[di] 
    sub dl,30h 
    mov dh,0 

    add ax,dx 

    Ret 
atoi endp 
+0

請格式正確的代碼... – trojanfoe

回答

1

問題是「mul dl」。 DL是一個8位寄存器,所以最大值DL可以保持爲255.您可能正確乘以100(例如「99 * 100 + 9 = 999),然後不能乘以1000或更高。代碼需要使用較大的寄存器中的代碼也需要重寫,以便它只每個字符做一個MUL

實施例(NASM,未測試):

atioi: 
    xor eax,eax 

.nextChar: 
    movzx ebx,byte [di] 
    inc di 
    sub bl,'0' 
    jb .invalidChar 
    cmp bl,9 
    ja .invalidChar 
    lea eax,[eax*4+eax] 
    sub ecx,1 
    lea eax,[eax*2+ebx] 
    jne .nextChar 
    ret 

.invalidChar: 
    ; Not sure what you're planning to do with error handling.. 

上述代碼假定一個80386或更高CPU(並且以實模式或16位代碼工作),並且應該適當地處理高達「2 ** 32-1」(超過40億)的值。

對於在出生前(80286及更早版本)可能已經過時的80x86 CPU,您需要使用一對寄存器(例如, DX:AX)而不是32位寄存器來獲得相同的範圍,或將其限制爲小於65536的結果,並使用16位寄存器而不是32位寄存器(例如,用BX替換EBX,用AX替換EAX,等等)。

1

這是相當可怕的:)

無論如何,直接原因爲什麼它不工作的是,你正在使用8次乘法,尤其是mul dlmul bl幾乎沒有發生1000的工作,但也將失敗10000和以上。

一般建議:學會使用調試器來遍歷代碼,看看它出錯的地方。

+0

+1的一般建議;) – BlackBear