DSTR struc
kkk dd ?
darr dd 256 dup (?)
DSTR ends

BSTR struc
cc dd ?
barr dd DSTR 50 dup (<>)
BSTR ends

ASTR struc
aarr BSTR 50 dup (<>)
ASTR ends

.data?
carr ASTR 2 dup (<>)

.code



; lpAstr is the pointer of ASTR
testFun proc lpAstr:DWORD,i:DWORD,j:DWORD,k:DWORD,p:DWORD
mov edi, lpAstr


; but how can easy to access the darr[], for example
; for example i want to add 5 to darr[9]
; i fond it it very difficult in masm, but C code is easy


ret
testFun endp





for example as C code

carr.aarr.barr.darr +=5
// i, j, k, p is variable
Posted on 2005-01-29 10:26:45 by jndk
add .ASTR.aarr.barr.darr[9*4],5

I find this pretty easy

Of course you will have to do some array calculations if it is not aarr[0] and barr[0] what has to be accessed, for example to access

aarr[0].barr.darr[9]:

mov eax, k
mov ecx, sizeof DSTR
imul eax, ecx
add .ASTR.aarr.barr.darr[9*4],5
Posted on 2005-01-29 10:37:44 by japheth
is this correct


mov edi, lpAstr
mov eax, j
mov ebx, sizeof BSTR
mul ebx
add edi, eax
mov eax, k
mov ebx, sizeof CSTR
mul ebx
add edi, eax
mov eax, p
mov ecx, 5
add [edi+eax*4] , ecx
Posted on 2005-01-29 10:41:18 by jndk
add .ASTR.aarr.barr.darr[9*4],5

I find this pretty easy


maybe your code is carr.aarr[0].barr[0].darr+=5

but i want carr.aarr.barr.darr+=5
Posted on 2005-01-29 10:44:33 by jndk
Like this?

mov eax,i
imul eax,eax,50
add eax,j
imul eax,eax,12851
movzx ecx,k
mov ch,cl
add eax,ecx
add eax,p
mov ecx,
add dword ptr ,5
ret
Posted on 2005-01-29 10:55:57 by Sephiroth3
sorry i can not understand the code

imul eax,eax,12851

can you explain to me

i mean is eax*eax+12851?

thanks
Posted on 2005-01-29 11:45:18 by jndk
jdnk,
You are specifying such large data areas with your nested arrays that MASM does not assemble within a reasonable time. 256*50*50*2 DWORDS= 5120000 bytes! Therefore I have reduced the size of the arrays to illustrate the method. Note also that numbers with brackets like value[20] must be in bytes, not data units like DWORDs or STRUCtures. Ratch



DSTR STRUC
KKK DWORD ?
DARR DWORD 64 DUP (?)
DSTR ENDS

BSTR STRUC
CC DWORD ?
BARR DSTR 25 DUP (<>)
BSTR ENDS

ASTR STRUC
AARR BSTR 25 DUP (<>)
ASTR ENDS

CARR STRUC
BEGCARR ASTR 2 DUP (<>)
CARR ENDS

.DATA?
BUFFER BYTE 80 DUP (?)

ARRAY1 CARR <>

DWORD ?

.CODE
MAIN:
;reference carr[1].aarr[3].barr[20].darr[15]

MOV EAX,[ARRAY1.BEGCARR[1*ASTR].ASTR.AARR[3*BSTR].BSTR.BARR[20*DSTR].DSTR.DARR[15*DWORD]]
ADD EAX,5
MOV [ARRAY1.BEGCARR[1*ASTR].ASTR.AARR[3*BSTR].BSTR.BARR[20*DSTR].DSTR.DARR[15*DWORD]],EAX
Posted on 2005-01-29 14:14:38 by Ratch
thanks

but i mean must be variable of the index

the four struct is only a exmaple, i want to know how c runtime to do this, are there many mul operation to find the address of carr.aarr.barr.darr, it may too slow,

so i really code is avoid such complex struct, but i want to know is there good way to do this, because use struct is more ealy understand
Posted on 2005-01-30 00:57:35 by jndk
jndk,


the four struct is only a exmaple, i want to know how c runtime to do this, are there many mul operation to find the address of carr.aarr.barr.darr, it may too slow,


Too slow? What do you mean by that? There are 3 MULs necessary. The code below calculates the offset into the array dynamically. I believe that is what you want. Ratch




DSTR STRUC
KKK DWORD ?
DARR DWORD 64 DUP (?)
DSTR ENDS

BSTR STRUC
CC DWORD ?
BARR DSTR 25 DUP (<>)
BSTR ENDS

ASTR STRUC
AARR BSTR 25 DUP (<>)
ASTR ENDS

CARR STRUC
BEGCARR ASTR 2 DUP (<>)
CARR ENDS

.DATA?
BUFFER BYTE 80 DUP (?)

ARRAY1 CARR <>

DWORD ?

.DATA
i DWORD 1
j DWORD 3
k DWORD 20
l DWORD 15

.CODE
; ------------------------------------------------------------------------------
INDEX$1 STRUC
return DWORD ?
ADR1=$
array DWORD ?
I DWORD ?
J DWORD ?
K DWORD ?
L DWORD ?
ADR2=$
INDEX$1 ENDS

S$1 EQU ESP.INDEX$1

INDEX:
MOV EAX,ASTR
MOV ECX,[S$1.array]
MUL [S$1.I]
ADD ECX,EAX
MOV EAX,BSTR
MUL [S$1.J]
ADD ECX,EAX
MOV EAX,DSTR
MUL [S$1.K]
ADD ECX,EAX
MOV EAX,[S$1.L]
LEA EAX,[ECX+DWORD*EAX+2*DWORD] ;2*DWORD must be added for extra DWORDS in BSTR in ASTR

RET ADR2-ADR1
; ------------------------------------------------------------------------------

MAIN:
;reference carr[1].aarr[3].barr[20].darr[15]

MOV EAX,[ARRAY1.BEGCARR[1*ASTR].ASTR.AARR[BSTR*3].BSTR.BARR[20*DSTR].DSTR.DARR[15*DWORD]]
ADD EAX,5
MOV [ARRAY1.BEGCARR[1*ASTR].ASTR.AARR[BSTR*3].BSTR.BARR[20*DSTR].DSTR.DARR[15*DWORD]],EAX

INVOKIT INDEX,@ ARRAY1,i,j,k,l
MOV ECX,[EAX]

Posted on 2005-01-30 10:58:26 by Ratch
but i want carr.aarr.barr.darr+=5

You will need to break this down to translate it to ASM.

p_aarr = carr.aarr;
p_barr = p_aarr.barr;
p_darr = p_barr.darr;

p_darr += 5;

    mov   ecx,i

imul ecx,sizeof ASTR
lea eax,carr[ecx].aarr

mov ecx,j
imul ecx,sizeof BSTR
lea eax,[eax + ecx].barr

mov ecx,k
imul ecx,sizeof DSTR
lea eax,[eax + ecx].darr

mov ecx,p
add DWORD ptr [eax + ecx*4],5

If you are randomly accessing the arrays, you can optimize the multiplications, but you cannot get rid of them.

If you embed this in nested loops, there is a pointer-based optimization (which you can code in C!)
Posted on 2005-01-30 18:22:51 by tenkey
tenkey,
Did you test your code? Then you know it does not assemble without errors, right? And you cannot put registers within index [] and expect MASM to compute the value of the registers dynamically. And why do you specify the signed IMUL instead of MUL? Did your code also take into consideration that the embedded array might not be the first data within the outer array? Take a look at my code above. It shows an example of a static and dynamic reference, and they both return the same address. Ratch
Posted on 2005-01-30 19:55:21 by Ratch
There exists no immediate MUL. IMUL ecx, sizeof ASTR is short for IMUL ecx, ecx, sizeof ASTR (To Jndk: this instruction performs WORD or DWORD multiplication on the second operand, which is a register or memory reference, and the third operand, which is an full size immediate value or sign extended byte, and stores the result in the first operand, which is a register). The only problem in tenkey's code is that the two latter LEA instructions fail to specify which structure to use. However, note that the innermost structure contains the factor 257, which can be reduced to a MOV instruction instead of an IMUL. The factor 4 applies to all of the structures, and may thus be encoded in the final address.
Posted on 2005-01-31 13:44:12 by Sephiroth3
Sephiroth3,


There exists no immediate MUL.

True, but where is the need in this case?

The only problem in tenkey's code is that the two latter LEA instructions fail to specify which structure to use.


There is more than that. One cannot code lea eax,.barr no matter what structure is specified. Also his algo fails to take into account that the 2 of the inner arrays are not the first elements of their structures. Therefore his code sequence will not give the correct value. Ratch
Posted on 2005-01-31 16:22:14 by Ratch
You can write lea eax,.bstr.barr, and it will assemble fine, producing lea eax,.
I see you're right about the MUL though, now that I think about it. 3 bytes could be eliminated in tenkey's code through the use of MUL, although my code above wouldn't benefit from it.
But tenkey's code should produce the correct address, too, but in a roundabout way.
Posted on 2005-01-31 16:56:43 by Sephiroth3
Sephiroth3 ,
You can write lea eax,.bstr.barr, and it will assemble fine, producing lea eax,.


Have you tried it?

  00000076  67& 8D 06 0008	    LEA   EAX,D[BSTR.BARR[4]]

MOV EAX,BSTR[1].BARR
JNDK.ASM(101) : error A2006: undefined symbol : BARR

0000007B 8B 0D 00000004 R mov ecx,j
00000081 69 C9 00001968 imul ecx,sizeof BSTR
lea eax,[eax + ecx].BARR
JNDK.ASM(105) : error A2006: undefined symbol : BARR

00000087 8B 0D 00000008 R mov ecx,k
0000008D 69 C9 00000104 imul ecx,sizeof DSTR
lea eax,[eax + ecx].DARR
JNDK.ASM(109) : error A2006: undefined symbol : DARR
lea eax,[eax+ecx].bstr.barr
JNDK.ASM(110) : error A2006: undefined symbol : bstr

00000093 8B 0D 0000000C R mov ecx,l


But tenkey's code should produce the correct address, too, but in a roundabout way.


I will believe it when I see the errors fixed and tested. I know my code is correct because I tested it. Ratch
Posted on 2005-01-31 18:59:30 by Ratch
So I've spent too much time with TASM. I only changed SIZE to SIZEOF.

Here's a snippet of the corrected conversion of TASM code. I assembled it with MASM. I allocated carr in another file, and used LEA to avoid bad memory access. I ran this through a debugger (Visual Studio) because I didn't want to mess with pretty output. Registers EBX and EDX contain the same value.

You can easily see the pattern, which is my intent with the code.

	externdef carr:ASTR


mov i,1
mov j,5
mov k,7
mov p,125

mov ecx,i
imul ecx,size ASTR
lea eax,carr[ecx].ASTR.aarr

mov ecx,j
imul ecx,size BSTR
lea eax,[eax + ecx].BSTR.barr

mov ecx,k
imul ecx,size DSTR
lea eax,[eax + ecx].DSTR.darr

mov ecx,p
lea edx,[eax + ecx*4]
; add DWORD ptr [eax + ecx*4],5

lea ebx,carr[1*ASTR].aarr[5*BSTR].barr[7*DSTR].darr[125*DWORD]
; mov eax,carr[1*ASTR].aarr[5*BSTR].barr[7*DSTR].darr[125*DWORD]
Posted on 2005-02-01 00:53:57 by tenkey
tenkey,

I don't know about TASM, but the LEA instruction below does not assemble with MASM. Also the <lea eax,.DSTR.DARR> instruction assembles as <LEA EAX,> . Is that what you want? Ratch



0000008F 8B 0D 00000000 R mov ecx,i
00000095 69 C9 00027B28 imul ecx,size ASTR
0000009B 8D 81 0004F650 lea eax,CARR[ecx].ASTR.AARR

000000A1 8B 0D 00000004 R mov ecx,j
000000A7 69 C9 00001968 imul ecx,size BSTR
000000AD 8D 44 01 04 lea eax,[eax + ecx].BSTR.BARR

000000B1 8B 0D 00000008 R mov ecx,k
000000B7 69 C9 00000104 imul ecx,size DSTR
000000BD 8D 44 01 04 lea eax,[eax + ecx].DSTR.DARR
000000C1 8D 44 01 04 LEA EAX,[EAX+ECX+DSTR.DARR]

000000C5 8B 0D 0000000C R mov ecx,l
000000CB 8D 14 88 lea edx,[eax + ecx*4]
; add DWORD ptr [eax + ecx*4],5

lea ebx,CARR[1*ASTR].AARR[5*BSTR].BARR[7*DSTR].DARR[125*DWORD]
JNDK.ASM(119) : error A2006: undefined symbol : AARR
; mov eax,CARR[1*ASTR].AARR[5*BSTR].BARR[7*DSTR].DARR[125*DWORD]
Posted on 2005-02-01 05:43:44 by Ratch
Of course it doesn't work with your code. You didn't declare CARR the same way I did. The original post declared CARR as a DUP'ed ASTR in the .data? section. The ASTR in CARR.ASTR.AARR is redundant when CARR is declared as an ASTR.

Also the <lea eax,.DSTR.DARR> instruction assembles as <LEA EAX,> . Is that what you want? Ratch

Yes, it's what I want. DSTR is a template, not a label or offset. You can see that it produces the correct offset of 4 for the beginning of DARR.
Posted on 2005-02-01 14:57:32 by tenkey
tenkey,
Of course it doesn't work with your code. You didn't declare CARR the same way I did.


Thanks for pointing that out. I should have seen that. I used CARR LABEL ASTR instead of EXTERNDEF and got correct results. Both of our codings are in agreement. Ratch
Posted on 2005-02-01 23:07:47 by Ratch