The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: vivendi on September 30, 2006, 02:32:12 PM

Title: counting help
Post by: vivendi on September 30, 2006, 02:32:12 PM
Hello, i want to write a simple app, that store's the value's 1,2,3,4,5 in a different memory location, and while its storing the number '1' in the first location, i need another register that counts all the numbers.
So if the numbers 1 to 5 are stored, then another register should have the result '15', cause thats the total of 1+2+3+4+5.

My main problem is the storing in different memory locations, im not sure how to start with this. So i was hoping someone here could help me on my way.
Title: Re: counting help
Post by: hutch-- on September 30, 2006, 02:47:46 PM
This sounds like homework but we will forgive you this time. Here is how you do it in 32 bit MASM code.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .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
Title: Re: counting help
Post by: vivendi on September 30, 2006, 03:05:29 PM
Thanks alot!
I tried this code, but how can i tell what the value of eax is at the end? I see you're using "print str$(eax),13,10", but it doesnt look like it's printing any value... Any idea why?
Title: Re: counting help
Post by: hutch-- on September 30, 2006, 11:26:30 PM
Make sure you build it as CONSOLE, not GUI.
Title: Re: counting help
Post by: Vortex on October 01, 2006, 10:08:24 AM
Another one :

.386
.model flat,stdcall
option casemap:none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\user32.inc
include     \masm32\include\masm32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib  \masm32\lib\masm32.lib

.data
numbers     dd 1,2,3,4,5        ; we define an array to handle easily the sequence of numbers
message     db 'Sum = %d',0     ; %d will be replaced by the sum of the array members

.data?
buffer      db 100 dup(?)       ; we allocate an uninitialized data block of 100 bytes
                                ; to store the final state of the "message" string processed
                                ; by wsprintf - 100 is an arbitrary value, you could set the
                                ; value depending on the exact final size of "message"
.code

start:

    xor     eax,eax
    mov     edx,OFFSET numbers  ; we set a pointer to the array of 5 integers
                                ; "OFFSET numbers" holds the address of the array
                                ; mov edx,numbers -> edx will be simply set to "1" , the value
                                ; of the first array member
    mov     ecx,5
@@:
    add     eax,DWORD PTR [edx] ; DWORD PTR [edx] retrieves the value of each integer, edx points
                                ; the address of the array
    add     edx,4               ; edx is a full 32-bit register, so we have to increment edx by 4
                               
    dec     ecx                 ; if ecx == 0 then the ZERO flag is set to TRUE
    jnz     @b                  ; after dec ecx, jump to the nearest anonymous label @@ if the
                                ; ZERO flag is FALSE
    invoke  wsprintf,ADDR buffer,ADDR message,eax
                                ; %d is the only parameter specified in the definition of "message"
                                ; eax holds the sum and wsprintf will dump the the string "Sum = 15"
                                ; to the temporary memory block named "buffer"
    invoke  StdOut,ADDR buffer  ; StdOut prints text to the console, wsprintf writes the formatted string specified by
                                ; "message" to the memory block pointed by ADDR buffer
    invoke  ExitProcess,0       

END start

[attachment deleted by admin]
Title: Re: counting help
Post by: vivendi on October 01, 2006, 10:15:16 AM
Thanks alot Vortex, thats actually the code i needed. I know this, cause i saw that the teacher had something simulair. He also had this line at the top: "numbers     dd 1,2,3,4,5"

I haven't tried it out yet, not really checked the code out, have to see if i understand whats going on in the code.

BTW, how do i build as console? I used this command to build my asm file:

C:\masm32\bin> build.bat filename
Title: Re: counting help
Post by: Vortex on October 01, 2006, 10:33:57 AM
To build the project as console application :

C:\masm32\bin> buildc.bat filename

build.bat is designed for GUI applications.
Title: Re: counting help
Post by: vivendi on October 01, 2006, 11:29:37 AM
Thanks again, it works fine now :)

Just a last request though, would you mind explaining some things about the code..?
I've tried to comment it, but could you please help me with the parts that i dont understand.
I know i still have alot to learn, but i think this code is a great help if i inderstand what's going on.

Here's what i've commented.

.data
numbers     dd 1,2,3,4,5          ;Not sure what dd is for, creating some sort of an array?
message     db 'Sum = %d',0       ;Defining a string, where %d is replaced with a decimal value.

.data?                            ;Why .data again but then with a '?'... ???
buffer      db 100 dup(?)         ;Dont know what this is for...

.code

start:

    xor     eax,eax               ;make sure eax is empty/initialised.
    mov     edx,OFFSET numbers    ;Whats happening here? OFFSET? Why not just 'mov edx, numbers'
    mov     ecx,5                 ;the number 5 is placed in ecx for the loop
@@:
    add     eax,DWORD PTR [edx]   ;dont know why you're using DWORD PTR, but you obviously are adding the number of edx to eax everytime it loops
    add     edx,4                 ;Same here, not sure why the number 4 is placed in edx, it thought it already contained 'numbers'
    dec     ecx                   ;DECrease ecx
    jnz     @b                    ;Jump if not zero, but how does it know that its checking for ecx, and what is @b for? I only see a label called @@...
    invoke  wsprintf,ADDR buffer,ADDR message,eax           ;i know that wpsrintf is used to put variables together from the C language, but its kinda unclear here for me, the value of eax is probably placed in %d
    invoke  StdOut,ADDR buffer    ;StdOut, prints text to the screen? Why buffer, and not message...
    invoke  ExitProcess,0       

END start
Title: Re: counting help
Post by: Vortex on October 01, 2006, 12:58:46 PM
vivendi,

I modified the text of my posting above to display the commented version of the source code.

An additional note, here is a table of value of values , edx vs integers pointed by edx. You can examine it with the help of a debugger like Ollydbg :

edx               integer pointed by edx
======       ==============

00402000      1
00402004      2
00402008      3
0040200C      4
00400210      5

Attached is a screenshot taken from a debugging session with Ollydb

[attachment deleted by admin]
Title: Re: counting help
Post by: Boucly on October 01, 2006, 01:13:36 PM
Hi, vivendi,

Quotenumbers     dd 1,2,3,4,5          ;Not sure what dd is for, creating some sort of an array?
dd is double word, hence 32-bitor 4 bytes. It is an array declaration indeed. Each value has a memory size of dd

Quote.data?                            ;Why .data again but then with a '?'... ???
Quote
From Iczelion's Win32 Asm tutorial
.DATA    This section contains initialized data of your program.
.DATA?  This section contains uninitialized data of your program. Sometimes you just want to preallocate some memory but don't want to initialize it. This section is for that purpose. The advantage of uninitialized data is: it doesn't take space in the executable file. For example, if you allocate 10,000 bytes in your .DATA? section, your executable is not bloated up 10,000 bytes. Its size stays much the same. You only tell the assembler how much space you need when the program is loaded into memory, that's all.
.CONST  This section contains declaration of constants used by your program. Constants in this section can never be modified in your program. They are just *constant*.

Quotebuffer      db 100 dup(?)         ;Dont know what this is for...
buffer name of the variable (you know that of course). db = double byte. 100 dup(?) 100 copies of what's in the bracket, in other words an array of the value in the bracket. ?, Might have to find someone else to answer that, not sure myself.

Quotexor     eax,eax               ;make sure eax is empty/initialised.
Zero eax. Faster in processing than mov eax, 0.

Quotemov     edx,OFFSET numbers    ;Whats happening here? OFFSET? Why not just 'mov edx, numbers'
OFFSET numbers The location (offset) of the variable numbers. In an array is it the location of the first variable.

Sorry I ran out of time.  :( Good luck  :U

Boucly
Title: Re: counting help
Post by: Seb on October 01, 2006, 02:09:12 PM
Quote from: Boucly on October 01, 2006, 01:13:36 PM
buffer      db 100 dup(?)         ;Dont know what this is for...

Sorry for going off-topic, but doesn't db mean declare byte? :red

Regards,
Seb
Title: Re: counting help
Post by: Boucly on October 01, 2006, 02:15:48 PM
Quote from: Seb on October 01, 2006, 02:09:12 PM
Quote from: Boucly on October 01, 2006, 01:13:36 PM
buffer      db 100 dup(?)         ;Dont know what this is for...

Sorry for going off-topic, but doesn't db mean declare byte? :red

Regards,
Seb

Sorry, you're right Seb. Thanks for correcting me. I researched on it and **I was right for the past three months  :red :P

Quote
From http://web.cs.wpi.edu/~jburge/courses/c02/cs2011/lectures/Lecture7.PDF (http://web.cs.wpi.edu/~jburge/courses/c02/cs2011/lectures/Lecture7.PDF)

Data Allocation
Directives
• Data allocation directives
allocate storage based on
several predefined types:
– DB – define byte (1 byte)
–DW – define word (2 bytes)
– DD – define doubleword (4 bytes)
– ... and more for larger data types
(up to 10 bytes)

EDIT: I had learned a lot more by helping others than trying to get pity by being a newbie. And that's somehting I learned in the last month or so.

**EDIT: "I was wrong" not "I was right"
Title: Re: counting help
Post by: Vortex on October 01, 2006, 02:30:30 PM
buffer      db 100 dup(?)

This statements creates an array named buffer containing 100 uninitialized bytes.
Title: Re: counting help
Post by: vivendi on October 01, 2006, 02:50:12 PM
Thanks alot for helping me with the code!!
At first it looked pretty hard, but i've been playing around with it after the explanations, and i start to understand most of it now!

So thanks again for helping me out :)
Title: Re: counting help
Post by: vivendi on October 01, 2006, 04:21:38 PM
Sorry, but im having some trouble again  :red

I'm trying to change the code so that it asks for a user input. All i added was a line to .data?


.data?
  buffer db 100 dup(?)
  gNummers  dd 100 dup(?)    ;this one is new


And i added a line in the .code section


.code


start:

  xor eax, eax ;zero eax

  invoke StdIn,gNummers, LENGTHOF gNummers


When i compile and run the app, then eveything seems fine at first, cause it does ask for an input. I can enter any number i want and then i get the result of the old app i was asking for at first, which should give '15' as a result.
But im getting 18... No matter what number i enter.

And if i remove the two lines i added then everything is back to normal. So why is the output 18 when i add my two lines of code...??? Thats really something i don't understand...
Title: Re: counting help
Post by: Vortex on October 01, 2006, 05:14:39 PM
vivendi,

StdIn puts a CR+LF pair to the end of the buffer receiving keyboard input. You need to remove those ASCII characters to convert the string contained in the buffer to a DWORD value. atodw convers a NULL terminated string to a DWORD

Quoteatodw

atodw proc uses edi esi String:PTR BYTE

Note that the parameter String is an address of DWORD size.

Description
atodw converts a decimal string to dword.

Example
invoke atodw,ADDR MyDecimalString

Parameter
   1. String The address of the decimal string to convert

Return Value
The DWORD value is returned in eax.

Notice that StdIn returns the number of keyboard strokes passed to the buffer pointed by this function.

Here is another version of the counter demo :

.data?
buffer          db 100 dup(?)       ; we allocate an uninitialized data block of 100 bytes
                                ; to store the final state of the "message" string processed
                                ; by wsprintf - 100 is an arbitrary value, you could set the
                                ; value depending on the exact final size of "message"
input_buffer    db 100 dup(?)

.code

start:
    invoke  StdIn,ADDR input_buffer,100 ; receive input from keyboard
                                        ; notice that StdIn will write the CR+LF pair to the buffer
    sub     eax,2
    mov     BYTE PTR [input_buffer+eax],0 ; stripping the CR+LF pair, ASCII 13,10
    invoke  atodw,ADDR input_buffer     ; atodw converts a decimal string to dword   
    cmp     eax,5                       ; check the return value stored in eax
    jbe     @f                          ; if eax<=5 then jump to the nearest next anonymous label
    invoke  StdOut,ADDR errmsg          ; eax greater than 5? Display an error message and
    jmp     start                       ; go back to receive another input

@@:
    mov     edx,OFFSET numbers  ; we set a pointer to the array of 5 integers
                                ; "OFFSET numbers" holds the address of the array
                                ; mov edx,numbers -> edx will be simply set to "1" , the value
                                ; of the first array member
    mov     ecx,eax
    xor     eax,eax
    .
    .



[attachment deleted by admin]
Title: Re: counting help
Post by: vivendi on October 01, 2006, 06:25:59 PM
Thanks alot, you pretty much made my homework :)

I still need to change some things though. What i need, is a program that first asks how much numbers i want to use, so lets say i enter '5'.
Then after that it should ask, enter 5 different numbers, so if i enter, 1,2,3,4,5 then it should give me the sum of those numbers.

Now i've got a good start with the help of you guys, and especially with the sourcecode you just provided. But i wanted to start all over and do the rest myself.

But again, i got stuck iwth the StdIn part.
I have this code right now:


.data
  numbers dd 1,2,3,4,5
  message db 'Total is %d'


.data?
  buffer db 100 dup(?)
  input_buffer dd 100 dup(?)

.code


start:

  invoke StdIn, ADDR input_buffer, 100
  sub eax, 2
  mov BYTE PTR [input_buffer+eax],0
  invoke atodw, ADDR input_buffer

  invoke wsprintf,ADDR buffer,ADDR message, ADDR input_buffer
  invoke StdOut, ADDR buffer

  invoke ExitProcess,0


END start


It asks me to enter a number, and it should display that number right after that, but i get something like this instead: 4206724

I've tried to mov it in eax, tried to change it to BYTE PTR [input_buffer] and some other things, but all failed.
So what am i doing wrong this time... :(
Title: Re: counting help
Post by: Vortex on October 01, 2006, 06:50:18 PM
Have a look at the comments :

Quote.data
message         db 'The number you entered is %d',0 ; You should put the NULL string terminator

.data?
buffer          db 100 dup(?)
input_buffer    db 100 dup(?) ; db instead of dd

.code


start:

  invoke    StdIn, ADDR input_buffer, 100
  sub       eax, 2
  mov       BYTE PTR [input_buffer+eax],0
  invoke    atodw, ADDR input_buffer ; the result is stored in eax
  invoke    wsprintf,ADDR buffer,ADDR message,eax ; eax holds the number converted to DWORD
  invoke    StdOut, ADDR buffer
  invoke    ExitProcess,0


END start
Title: Re: counting help
Post by: ecube on October 01, 2006, 10:23:04 PM
Quote from: vivendi on October 01, 2006, 10:15:16 AM
Thanks alot Vortex, thats actually the code i needed. I know this, cause i saw that the teacher had something simulair. He also had this line at the top: "numbers     dd 1,2,3,4,5"

I haven't tried it out yet, not really checked the code out, have to see if i understand whats going on in the code.

BTW, how do i build as console? I used this command to build my asm file:

C:\masm32\bin> build.bat filename


i'm shocked you're learning asm/masm from a teacher, I wish I had that luxury. Even all the asm books i've seen written are dos based. Keep with it asm is a fantastic language and masm32 a excellent package.
Title: Re: counting help
Post by: vivendi on October 02, 2006, 05:18:10 AM
Quote from: E^cube on October 01, 2006, 10:23:04 PM
Quote from: vivendi on October 01, 2006, 10:15:16 AM
Thanks alot Vortex, thats actually the code i needed. I know this, cause i saw that the teacher had something simulair. He also had this line at the top: "numbers     dd 1,2,3,4,5"

I haven't tried it out yet, not really checked the code out, have to see if i understand whats going on in the code.

BTW, how do i build as console? I used this command to build my asm file:

C:\masm32\bin> build.bat filename


i'm shocked you're learning asm/masm from a teacher, I wish I had that luxury. Even all the asm books i've seen written are dos based. Keep with it asm is a fantastic language and masm32 a excellent package.

I wish it was all that great, my teacher works with a simulator called zep2, which uses instructions like, load and store and org etc. Instructions you dont see with a normal asm language like NASM, MASM etc..
So i choosed to convert all the assignments that are made for the zep2 environment, to MASM code. Which is pretty hard btw! But educational.

Anyway, i've been searching and coding all night long, some things went pretty good on my own, but theres this one thing i couldn't figure out. Not even wiith the help of google.

In the code above i've got that array: numbers dd 1,2,3,4,5

And i know how to store a value with user input. But how do i store an array like that?? A user must be able to enter 5 different numbers, and those 5 must be stored in an array like that. But how can this be done!?

Title: Re: counting help
Post by: Boucly on October 02, 2006, 03:07:58 PM
vivendi,

I asssume that you uses MASM32. Read the .asm files in C:\masm32\tutorial\console\, especially demo6\ and demo7\. Take a look if you understand. I just learned it myself. :bg Array addressing relies on referencing and addressing and adding numbers after it.

Boucly