News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Help with MASM-Arrays

Started by john113, March 10, 2008, 03:49:20 PM

Previous topic - Next topic

john113

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


ramguru

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

john113

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

BogdanOntanu

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.

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

BogdanOntanu

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.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

john113

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]




BogdanOntanu

You "read" but you do not understand.... read again but this time pay more attention.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

john113

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?



BogdanOntanu

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?
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

john113

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..??



BogdanOntanu


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?
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

john113

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??)

ramguru

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

BogdanOntanu

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.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

Vortex

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]