hi there,

I got a little problem there. I have an array of strucs. Let the struc consist of 3 DWORDS and the array of 10 of these strucs. When I now acces in my prog this array with ie: mov ebx,3; mov eax,myarray.firstdword; I got the following problem: eax has now the value of a myarray.firstdword but beginning 3 bytes + the address of myarray.
Aka why does my TASM not remember that the array consisted of strucs and handles it like an array of bytes,? Though it still remembers that there is a firstdword member?

Thanks ahead

atcl
Posted on 2007-04-25 05:59:57 by atcl
MASM code likely similar to TASM.


.586
.model flat,stdcall
option casemap:none

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

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

.data
item3 struct
  firstdword  dword ?
  seconddword dword ?
  thirddword  dword ?
item3 ends

myarray item3 10 dup (<1,2,3>)  ; 10 spots each 3 dwords  index 0 to 9

.code
start:

  xor ebx, ebx
  mov eax, myarray.firstdword    ; index 0  starts at byte  0

  add ebx, 3*4
  mov eax, myarray.firstdword    ; index 1  starts at byte 12

  add ebx, 3*4
  mov eax, myarray.firstdword    ; index 2  starts at byte 24

  invoke ExitProcess, 0
end start
Attachments:
Posted on 2007-04-25 08:24:59 by dsouza123
I agree totally, that is the way it should be!
Though the disassembly tells me otherwise: the line mov eax,myarray.firstdword
assembled and disassembled is mov eax,
Posted on 2007-04-25 08:40:13 by atcl
The syntax for MASM, and perhaps TASM, is quite flexible
the same statement can be specified a number of ways.

For example accessing the thirddword from index 2,
there are six versions displayed in the following code.


.code
start:

  xor ebx, ebx
  mov eax, myarray.firstdword      ; index 0  starts at byte  0 then add 0

  add ebx, 3*4
  mov eax, myarray.seconddword      ; index 1  starts at byte 12 then add 4

  add ebx, 3*4
  mov eax, myarray.thirddword      ; index 2  starts at byte 24 then add 8
  mov eax, myarray.thirddword      ; equivalent to the previous line
  mov eax, myarray.thirddword +     ; equivalent to the previous line
  mov eax, + myarray.thirddword    ; equivalent to the previous line
  mov eax,     ; equivalent to the previous line
  mov eax, dword ptr ; equivalent to the previous line


they all are encoded


  mov eax,
Posted on 2007-04-25 11:35:30 by dsouza123
Aka why does my TASM not remember that the array consisted of strucs and handles it like an array of bytes,? Though it still remembers that there is a firstdword member?

because TASM is an Assembler and not a Compiler.
imagine struct of size 17, how would you encode that in a single instruction?
"mov eax,"? -> NOT POSSIBLE. The "higher" languages calculate this for you (and generate one or more instructions) but not assemblers.
if "address in struct" evaluates to .data offset  (meaning you use constants) then you can
use single instruction:
mov eax,myarray[1*sizeof mystruct].firstdword
mov eax,myarray[99*sizeof mystruct].thirddword
otherwise, you have to calculate it:
imul eax,ebx,sizeof mystruct; EBX is index
mov eax,myarray.firstdword


Posted on 2007-04-25 12:00:27 by drizz
the *sizeof mystruc sounds very useful. I'll try that.
One comment though: How come the Assembler differentiates between BYTE, WORD + DWORD Arrays? It has to calculate the position at least for the basic types...
Posted on 2007-04-25 12:15:23 by atcl
as i already said, it does not. brackets [] don't have the same meaning as in "higher languages".
alternatively to sizeof you can also use TYPE keyword, which works on both types and variables.
imul sparereg,indexreg,TYPE myarray
imul sparereg,indexreg,TYPE mystruct
Posted on 2007-04-25 12:32:41 by drizz
An explanation of a line in a previous post

   add ebx, 3*4                  ; 12 bytes  calculated     3 dwords * 4 bytes per dword


this is a more flexible way to specify it, if item3's size changes you are still OK

   add ebx, sizeof item3         ; 12 bytes  because the size of item3 struct is 3 dwords


either is followed by

   mov eax, myarray.seconddword             ; index 1   starts at byte 12 then add 4


an alternative one line version,
possible because myarray is in .data and can be determined at assembly time

   mov eax, myarray[1*sizeof item3].seconddword  ; index 1   starts at byte 12 then add 4


thanks drizz for bringing to mind sizeof,
it prevents alot of errors later on
if there is a change in the size of some item.
Posted on 2007-04-25 14:32:21 by dsouza123
One comment though: How come the Assembler differentiates between BYTE, WORD + DWORD Arrays? It has to calculate the position at least for the basic types...

i forgot to mention that memory address encoding supports scale of 1,2,4 and 8..but thats it.
that matches arrays of byte,word,dword and qword.


Posted on 2007-04-26 10:21:14 by drizz
Ok, thats what i thought. Well, with sizeof and type everythings runs smoothly. Thanks.
Posted on 2007-04-26 10:22:54 by atcl