I am using MASM and currently implementing a loop displaying Capital alphabets, small alphabets and ASCII in between
.386
.model flat, stdcall
option casemap :none
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\masm32.inc
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\masm32.lib
.data
_ret sdword 13
_car sdword 10
_num sdword 0
.code
main:
mov edx, 'A'
mov ecx, 58
jmp _end
_loop:
push edx
invoke StdOut, esp
invoke StdOut, addr _ret
invoke StdOut, addr _car
pop edx
inc edx
dec ecx
_end:
cmp ecx, 0
jne _loop
_exit:
invoke ExitProcess, 0
end main
The problem here I am facing is that ECX is not decreasing during the body of the loop and the loop continue forever even after A-Z %somehere% a-z
Your issue is one of calling convention. You've set the default convention to .model flat, stdcall
which is not an issue. This means that unless otherwise specified stdcall calling convention will be used by the invoke
directive. The stdcall calling convention includes these rules:
- The volatile registers are: EAX, ECX, EDX, and ST0 - ST7
- The non-volatile registers are: EBX, EBP, ESP, EDI, ESI, CS, DS, ES, FS and GS
This means that you can't assume that the values in EAX, ECX, and EDX will remain the same after a call
/invoke
. Your loop variable is ECX so it is likely the calls to StdOut
clobbered ECX each time they were called leading to the infinite loop.
The best choice is to use one of the non-volatile registers EBX, EDI, ESI (you cause other issues if you use EBP and ESP). If you run out of registers you can:
StdOut
the same way that EDX was preserved in your code using PUSH/POP.