2014-04-01 65 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