The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: l46kok on March 28, 2012, 08:34:32 AM

Title: Loop Question
Post by: l46kok on March 28, 2012, 08:34:32 AM
Hello. I'm new to MASM32 and much help would be appreciated on the following code.

I made a very simple program to loop and print the numbers based on the count given.


.386
.model flat, stdcall
option casemap :none

include \masm32\include\masm32rt.inc

.code

start:

mov ecx, sval(input("Loop Count: "))
xor eax, eax

loop_start:

add eax, 1
cmp eax, ecx
print str$(eax)
jne loop_start

invoke ExitProcess,0

end start


The program gets stuck in the loop majorly because the print str$(eax) macro modifies eax,ecx alltogether.

How can I design the loop so that such problems don't occur? (Except for using the stack to save the values)
Title: Re: Loop Question
Post by: DataHarry on March 28, 2012, 09:31:45 AM
I know you wrote that you did not want to use push and pop, but I think that is the best way......

;.386
;.model flat, stdcall
;option casemap :none
; do not need these lines, they are included in the masm32rt.inc.

include \masm32\include\masm32rt.inc

.code

start:
    mov ecx, sval(input("Loop Count: "))
    xor eax, eax

loop_start:

    inc eax
    ; use inc eax instead of add (it is generally faster).

    push eax
    push ecx
        print str$(eax)
    pop ecx
    pop eax
    ; Print uses eax and ecx, you must push and pop them.

    ; your cmp has to be placed right before the jne.
    cmp eax, ecx
    jne loop_start

    inkey
    ; use inkey macro so that you can watch your output.


    invoke ExitProcess,0

end start

Title: Re: Loop Question
Post by: jj2007 on March 28, 2012, 09:49:00 AM
Quote from: DataHarry on March 28, 2012, 09:31:45 AM
    ; use inc eax instead of add (it is generally faster).

On modern CPUs, there is no difference, on older P4s, add is faster.

In addition to using push/pop, you can use ebx, esi and edi - regs that are not modified by Windows. More in my signature.
Title: Re: Loop Question
Post by: hutch-- on March 28, 2012, 11:26:14 AM
Here is a quick fiddle for you. I changed the EAX and ECX registers to ones that were not overwritten by the functions called and changed the loop logic. Also note that if you use the masm32rt include file, you don't need to specify the .386 etc as its already done. You do either one or the other.


include \masm32\include\masm32rt.inc

.code

start:

    push esi
    push edi

    mov edi, sval(input("Loop Count: "))
    xor esi, esi

  loop_start:
    add esi, 1
    cmp esi, edi
    jg loop_out
    print str$(esi),13,10
    jmp loop_start

  loop_out:
    pop edi
    pop esi

    invoke ExitProcess,0

end start