Yes, you are calling 'print str$(ecx)," "' which uses ecx register which is volatile register
and it gets trashed
you can use nonvolatile registers or PUSH and POP eg:
.for (ebx=3¦ebx>=1¦ebx--)
.for(ecx=1¦ecx<=ebx¦ecx++)
push ecx
print str$(ecx)," "
pop ecx
.endfor
print " ",13,10,0
.endfor
When you write print str$(ecx)," "
you use these two macros:
print MACRO arg1:REQ,varname:VARARG ;; display zero terminated string
invoke StdOut,reparg(arg1)
IFNB <varname>
invoke StdOut,chr$(varname)
ENDIF
ENDM
; ----------------------------------------------------------
; function position macros that takes a DWORD parameter and
; returns the address of the buffer that holds the result.
; The return format is for use within the INVOKE syntax.
; ----------------------------------------------------------
str$ MACRO DDvalue
LOCAL rvstring
.data
rvstring db 20 dup (0)
align 4
.code
invoke dwtoa,DDvalue,ADDR rvstring
EXITM <ADDR rvstring>
ENDM
as you can see they both call functions that do not preserve volatile registers