Hello, i've been trying to figure out how to create the folloing code with a loop, instead of repeating the steps.

(i did not write this)


include \masm32\include\masm32rt.inc
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib


.code

start:

    call main
    inkey
    exit


main proc

    LOCAL var1  :DWORD
    LOCAL var2  :DWORD
    LOCAL var3  :DWORD
    LOCAL var4  :DWORD
    LOCAL var5  :DWORD

    mov var1, 1
    mov var2, 2
    mov var3, 3
    mov var4, 4
    mov var5, 5

    xor eax, eax
    add eax, var1
    add eax, var2
    add eax, var3
    add eax, var4
    add eax, var5

    print str$(eax),13,10

    ret

main endp

end start


So what happends here is, there are 5 variable's created,  and in each variable is a number stored, from 1 to 5.
Then all the numbers must are added, 1+2+3+4+5=15 and that number is stored in a new location.

There thing that i wanted to change is, is the repeated steps, is there a way to make this shorter with a loop?

I know how to create a loop, but i wasnt sure how to increment the variable in the loop, so that the next number will be stored in 'var2' and so on...

So could anyone help me out with this?
Posted on 2006-09-30 11:11:22 by vivendi
Well all i can see is that the values 1, 2, 3, 4 and 5 are being added and then put into the EAX register and then printed out to the screen. All you have to do is to put the value explicitly into the EAX register as shown below:

Sum PROC
  MOV    ECX , 0000000Ah    ; Calculate the sum of 0..10
  XOR    EAX , EAX          ; EAX is initialized to zero
  @@__Sum:                    ; The main loop
    ADD    EAX , ECX        ; Add the current value of ECX to EAX
    DEC    ECX              ; Decrement the count register
    JNE    @@__Sum          ; Keep doing this until ECX!=0
  RET                        ; Return to the calling procedure
Sum ENDP
Now all you have to do is to feed the ECX register the upper boundary of your range. For example, if you want to calculate the sum of all the numbers between 1 to 20, you could move the value 00000014h to the ECX register at the first line of the "Sum" procedure.

Good luck.
Posted on 2006-09-30 11:40:34 by XCHG
Hey, not sure if i done this right, but i have something like this now:


include \masm32\include\masm32rt.inc
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib


.code

start:

call main
inkey
exit


main proc


mov ecx, 00000001h ;move the value 1 in ecx
xor eax, eax ;empty eax

DoCount:
add eax, ecx ;count the value of ecx to eax
inc ecx ;increase ecx
cmp ecx, 00000005h ;check if ecx equals to 5
jne DoCount ;loop again if not equal

print str$(eax),13,10
ret

main endp
end start


It counts to until it equals to the number 5, but meanwhile all the numbers are added to eax, which should have the number 15 at the end.
So is this code correct??
Posted on 2006-09-30 12:38:17 by vivendi
Yeah that code should work but a little hint, when you DECrement or INCrement, the zero flag is automatically set in the CPU Flags if the decremented or incremented number is equal to zero therefore you could simply use the "JNE" or "JNZ" conditional jumps right after INC or DEC to see if the number is zero. In the code you have written, ECX is getting incremented from 1 to 5 and thus would never become zero. Therefore you have used the CMP instruction. A better way is to decrement the ECX from the higher boundary to zero because this way all you have to do is to provide the upper boundary and not the lower due to the fact that the program automatically returns when all digits between Upper Boundary to the Lower Boundary are added together.

Posted on 2006-09-30 21:53:09 by XCHG
XCHG makes a good point, unless you have a very good reason to count "up" then it is always more efficient to count "down" to zero. If your lower limit is not zero it is sometimes better to adjust the number so that it will reach zero and make any adjustments in the loop to normalize the number. A conditional jump based strictly on flags avoids a cmp and thats always a good thing.
Posted on 2006-10-01 01:31:24 by donkey
Thanks, i get your point, but this is schoolwork, the techer told us to count to 5, so thats why i have to do this. But its always good to know that counting down is a better thing to do.

But as i said before, i didn't write this code, well, the middle part, but not this line:
"print str$(eax),13,10"

I was wondering what that is used for. It looks like it should display the value of eax, but i dont see anything. The .exe program just loads in my process list and just stays there.
Or isn't that line used to display anything..??

*edit*
I'm compiling this code as a Win32 app, but i have to compile it as a DOS app. That's what i've been told, but i dont know how to compile this as a console app.
Im using the following command to build.

C:\masm32\bin> build.bat filename
Posted on 2006-10-01 05:06:46 by vivendi
Try these commands in your console window:

ML /c /coff /nologo X.ASM
LINK /SUBSYSTEM:CONSOLE X.OBJ

Replace X in both of the lines with your source file name. For example if you are trying to assemble and link a file called PROG1.ASM as a console program, you would enter these commands in the console window:

ML /c /coff /nologo PROG1.ASM
LINK /SUBSYSTEM:CONSOLE PROG1.OBJ

Good luck.
Posted on 2006-10-01 10:36:53 by XCHG
The line "inkey" is probably waiting for a key press.
Posted on 2006-10-01 11:08:55 by tenkey