2014-04-01 101 views
1

我正在嘗試在MASM中編寫一個小程序,它將接收用戶輸入的字符串,從每個字符的ASCII值中減去4,然後輸出新字符。彙編程序奇怪的行爲

除了當調用StdOut時,這是大部分成功的,它不僅打印當前修改的字符,還打印下一個字符。

我一直在試圖弄清楚發生了幾個小時,但仍然沒有線索。這是我的代碼:

.486 
.model flat, stdcall 
option casemap :none 

include \masm32\include\windows.inc 
include \masm32\macros\macros.asm 

include \masm32\include\masm32.inc 
include \masm32\include\gdi32.inc 
include \masm32\include\user32.inc 
include \masm32\include\kernel32.inc 

includelib \masm32\lib\masm32.lib 
includelib \masm32\lib\gdi32.lib 
includelib \masm32\lib\user32.lib 
includelib \masm32\lib\kernel32.lib 

.data? 
    inputtxt dw 10000 dup(?) 
    current dd   ? 

.code 
start: 
    call main 
    exit 

main proc 
    Invoke StdIn, addr inputtxt, 10000 
    xor esi, esi 

    processLoop: 
     movzx eax, inputtxt[esi]  ; Get the character at index ESI 
     sub eax, 4      ; Subtract 4 from the character's ASCII code 
     mov current, eax    ; StdOut can't print a register 
     Invoke StdOut, addr current  ; Print the character: the problem lies here. 
     inc esi       ; Increment the loop counter 
     cmp byte ptr[inputtxt[esi]], 0 ; If the next character is NUL, we're done 
     jne processLoop     ; If it's not, loop again 
     ret 

main endp 

end start 

這裏的一個示例的輸入和輸出:

輸入:HE

輸出:DEA

DA都正確,但E是不正確的,在印刷與D相同。

請問現在沒有機智的人請嘗試弄清楚這裏發生了什麼?

+0

'movzx'得到32位字!不是一個8位的ASCII值。你必須使用'bl'8位寄存器來指向字符。 – Thanushan

回答

1

彙編程序假定您的movzx應該將16位數據轉換爲32位,因爲您尚未指定指令中源數據的大小。

添加byte ptr符:

; Move a byte from [inputtxt+esi] to eax, zero-extended 
movzx eax, byte ptr inputtxt[esi] 
+0

是的!太精彩了。我無法相信幾個小時前我沒有意識到這一點。我沒有意識到我必須指定源數據大小。無論如何,非常感謝。 – user184745