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.
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
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?
Make sure you build it as CONSOLE, not GUI.
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]
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
To build the project as console application :
C:\masm32\bin> buildc.bat filename
build.bat is designed for GUI applications.
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
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]
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
ddQuote.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
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
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"
buffer db 100 dup(?)
This statements creates an array named buffer containing 100 uninitialized bytes.
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 :)
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...
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
DWORDQuoteatodw
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]
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... :(
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
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.
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!?
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