I am attempting to write a small program in MASM that will take a string of user input, subtract four from the ASCII value of each character, then output the new character.
This is mostly successful, except when StdOut
is called, it prints not only the current modified character, but also the next character.
I've been trying to figure out what is happening for several hours and still don't have a clue. Here's my code:
.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
Here's a sample input and output:
Input: HE
Output: DEA
D
and A
are correct, but E
is incorrect and printed in the same pass as D
.
Will someone who isn't currently at wit's end please try to figure out what is going on here?
The assembler assumes that your movzx
is supposed to convert 16-bit data to 32-bit since you haven't specified a size for the source data in the instruction.
Add a byte ptr
specifier:
; Move a byte from [inputtxt+esi] to eax, zero-extended
movzx eax, byte ptr inputtxt[esi]