Hi
I wonderif someone could please help.
I am trying to declare an array and then trying move each element to a register to do some calculations.
Basically this is what I have done so far.
.data
MyArray DWORD 00100110b,00001111b,00000111b
total DWORD ?
.code ; Tell MASM where the code starts
start: ; The CODE entry point to the program
mov eax,[MyArray+esi]
mov eax,[MyArray+esi] ----> I could only load the first element using this. I have tried to do mov eax,[MyArray+esi*2] to load the secound element but it does not work.
Can somebody please point out where I am getting it wrong?
Thanks
mov eax,[MyArray+esi+0] ; 0-th
mov ebx,[MyArray+esi+4] ; 1-st
mov ecx,[MyArray+esi+8] ; 2-nd
mov edx,[MyArray+esi+12]; 3-rd
Hi
Thanks for the reply, I am trying to load each element then trying to add 30h to every element so I can convert them to ascii codes and display them.
.data
myarray db 00000110b,00000111b,00001111b,00000111b
total db ?
.code ; tell masm where the code starts
start: ; the code entry point to the program
mov al,[myarray+esi+8]
shr al,4
add al,30h
add total,al
invoke StdOut, addr[total]
on above I was tryng to display the secound element but instead of 7, I get 0 ??
Any idea why??
Thanks
You can do it as ramguru shows you...
But who does setup the ESI register there?
I see no code to do that... hence ESI could contain anything from zero up to 4Gigabyte... sometimes it will work but other times it will crash dramatically and other times it will show wrong results (but it will apparently work ok without a crash).
Conceptually you do not "declare" an array in MASM. Instead you know how an array (or vector in your case) is layout in memory and either statically reserve some space for it in the .data or .data? sections or dynamically allocate space for it at runtime and save the pointer.
If you statically allocate some space for it ... as you do apparently ... then the label where you allocate does contain the address of your "array"'s first element.
Again, if you fix the ESI part then you could do it like ramguru shows (easy and clear for a start) but for a much bigger array you should consider moving the address of your "array" into a register and thus obtaining "a pointer" to the first element of your array.
Then you can process your first element and when you are done with it IMHO your should consider incrementing the pointer in order to move to the next element. This way you will avoid having hard coded element position constants. Of course "incrementing the pointer" in fact means adding to it the size of your array's element.
Of course IF your "array" would really be an array then sometimes you would want to advance one "row" and in that case you should know how many element your array has on on "row".
Understanding "pointers" is of the essence in programming. You should note that at times a register can be used as containing a numerical value or at other times registers will contain pointers toward arrays or vectors or structure elements.
In MASM you load ESI with a pointer to you array first element like this:
mov esi, offset My_Array
The quotes around "array" are there in order to make you think that the array is just a concept into your brain.
For the CPU it is all just registers, bytes, dwords and memory addresses.
Oh and BTW... do not add ASCII numbers together and expect to get the correct result.
Convert to ASCII only as your last step before showing something "on screen".
And ... your Number to ASCII conversion routine is wrong.
Thanks for the reply, I read it and tried to modify my code but I still end up getting 0 as the result.
.data
myarray dword 00000110b,00000111b,00001111b,00000111b
total dword ?
.code ; tell masm where the code starts
start: ; the code entry point to the program
mov esi, [myarray]
mov eax,[myarray+esi+4]
shr eax, 24
and eax, 0fh
add eax, 30h
mov total,eax
invoke StdOut, addr [total]
You "read" but you do not understand.... read again but this time pay more attention.
to load the ESI register with the address of myarray;
mov esi, [myarray]
then use it as a pointer, so where am I going wrong?
In my message above ... what did I said about how to load ESI with the address of your array?
And running your program in your brain... Tell me what do you expect each of your code line to do?
ok..load the esi first using
mov esi, offset myarray
then if I do..
mov esi, offset myarray
mov eax, [esi]
mov total,eax
invoke StdOut, addr [total]
That will basically print out the first element of the array??
then to print the secound one I can inc the esi by 8 bits.
mov esi, offset myarray
mov eax, [esi+8]
mov total,eax
invoke StdOut, addr [total]
which should print out the secound element etc..??
mov esi, offset myarray
mov eax,[esi]
This should indeed give you the first element of your array.
Printing it is another issue :D. You need to convert the number to ASCII string first if you intend to print it to standard output.
There are functions in MASM that can help you do this...
But then... why do you do this:
mov eax [esi+8]
Ask yourself this: My array is made of what kind of elements? What are they? Bytes, words, dwords? What are the sizes of those elements in MASM? What are we accessing here: bits or bytes or dwords ?
Hint: byte=1 word=2 dword=4
Hence why [esi +8] ? How did you compute this hard coded value?
hmmmmmmm,
I was experimenting with MASM to load each element and print them out by adding 30h to each.
When I did
mov esi, offset myarray
mov eax,[esi]
it loaded the first element 00000110b and then when I tried to add 30h and display it, it gave out 6, which was correct.
second element is 00000111b, so I tried to add 4 bits so the pointer would move to 0111 then i can add 30h and display, which gave out 7. correct!
seems like if i keep incrementing 4,8,12 it will give access to each 4 bits in the array. (Maybe I can have a loop to do this and then add them to a display buffer??)
Sorry, john113, I think I made a little mistake
actually using esi (or whatever) with some constant number, like
[myarray+esi+4]
is good for more sophisticated structure like matrix or an array of structures
for regular array it's enough to write like this (if it's not declared like LOCAL)
mov eax,[myarray+0]
mov ebx[myarray+4]
Of course it's not good for dynamic array, only for fixed one
Quote
seems like if i keep incrementing 4,8,12 it will give access to each 4 bits in the array. (Maybe I can have a loop to do this and then add them to a display buffer??)
Incrementing with 4 will access each 4 bytes not 4bits. Learn to make the difference in between "bits" and "bytes" :D
Of course making a loop and incrementing your pointer instead of using hard coded offset will be the next natural step.
Adding 30h will "kind of work" for very small numbers. However it will fail for numbers greater than 9.
You do need a more elaborated number to ASCII string conversion routine. You can either write it yourself OR find one in MASM package that performs this conversion.
Hi john113,
Here is a quick example for you. This console application outputs an array of DWORD values. It uses the wsprintf function to convert the numbers to ASCII :
.386
.model flat,stdcall
option casemap:none
include DwordArray.inc
.data
array dd 16384,256,32768,8,100 ; all array members are DWORD values
string db 'Array member = %d',13,10
.data?
buffer db 100 dup(?)
.code
start:
call main
invoke ExitProcess,0
main PROC uses esi ebx
mov ebx,5
mov esi,OFFSET array
@@:
invoke wsprintf,OFFSET buffer,ADDR string,DWORD PTR [esi]
invoke StdOut,OFFSET buffer
add esi,4
dec ebx
jnz @b
ret
main ENDP
END start
[attachment deleted by admin]
Hi guys,
In the work I am suppose to use the "adding 30h" method, as the numbers are 0-9.
mov esi, offset myarray
mov eax, [esi]
add eax,30H
mov total,eax
mov eax, [esi+4]
add eax,30H
mov total,eax
mov eax, [esi+8]
add eax,30h
mov total,eax
mov eax, [esi+12]
add eax,30h
mov total,eax
mov eax, [esi+16]
add eax,30h
mov total,eax
mov eax, [esi+20]
add eax,30h
mov total,eax
mov eax, [esi+24]
add eax,30h
mov total,eax
I can get the first element to display using StdOut and it gives out correct answer "2". But the rest comes out as symbols. Any idea why?
using your way
total db 100 dup(?) ; it should be a string - an array of bytes
mov esi, offset myarray
mov eax, [esi]
add eax,30H
mov BYTE PTR [total+0],al
mov eax, [esi+4]
add eax,30H
mov BYTE PTR [total+1],al
mov eax, [esi+8]
add eax,30h
mov BYTE PTR [total+2],al
...
mov BYTE PTR [total+x],0 ; zero terminated string
Of course this code isn't very recommended, but it's your way, maybe for better understanding.
Is there anyway to display using StdOut after adding 30H to each element?
Now I'm confused in one your code-snippet you use ... "myarray": array of BYTES in another array of DWORDS
Quote from: john113 on March 10, 2008, 10:17:12 PM
Is there anyway to display using StdOut after adding 30H to each element?
It supposed to work when myarray is an array of dwords, otherwise (if bytes)
you should change code:
[esi+0]
[esi+1]
[esi+2]
...
Just know that BYTE is the base unit .. so it's 1, DWORD is 4
you add 1 if it's byte you add 4 if it's dword etc.
Hi
I dont really get what you say, my code so far....
.data
myarray dword 00000010b,01000000b,00010100b,011111100b
total dword ?
.code ; tell masm where the code starts
start: ; the code entry point to the program
mov esi, offset myarray
mov eax,[esi]
add eax,30h
mov total, eax
invoke StdOut, addr [total] ; this bit seems to work ok and output 2
mov eax, [esi+4]
add eax,30H
mov total, eax
invoke StdOut, addr [total] ;when I add this bit it only prints out "p" giving output "2p" when I am expecting "27"
Quote from: john113 on March 10, 2008, 07:29:45 PM
Hi guys,
In the work I am suppose to use the "adding 30h" method, as the numbers are 0-9.
So what the heck are you doing?
myarray dword 00000010b,01000000b,00010100b,011111100b
==
myarray dword 2,64,20,252
64 is not in range of 0-9
20 is not in range of 0-9
252 is not in range of 0-9
EDIT> I think I understood what you were trying to do. You wanted to get an index of the bit that was set...but it's not the proper way of doing it... 00010 and result 2 was just a coincidence :lol :lol :lol
Hey
I managed to declare the array as:
myarry db 0001b,0001b,1000b.........
then call each element,add 30h and display it....