News:

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

Accessing structure members "the hard way"

Started by Seb, November 19, 2006, 02:21:45 PM

Previous topic - Next topic

Seb

Hello there, MASM comrades! :bg

Would anyone mind telling me how I can access structure members returned from an external DLL without using either "assume" or "X ptr"?

I was hoping something like this would work...


; This is the ASM definition of the structure returned by the C DLL:
INFO struct
        fr     DWORD   ?
        chs    DWORD   ?
        fl    DWORD   ?
        ct    DWORD   ?
        orr  DWORD   ?
        pl   DWORD   ?
INFO ends

...

; I tried accessing the structure members by the index (fr=0, ch=1, fl=2 etc) and by multiplying with the size (4), didn't work though...
; EDX points to an INFO structure
mov eax, [edx+0*4]      ; fr
mov ecx, [edx+1*4]      ; chs

; Then I also tried accessing them by the index and by multiplying with the alignment (which I'm only guessing would be 8), without any success...
; EDX points to an INFO structure
mov eax, [edx+0*8]      ; fr
mov ecx, [edx+1*8]      ; chs


Any help on this would be greatly appreciated.

Regards,
Seb

Seb

I solved it. It seems I had been making a little mistake yesterday when I tested it, because the [edx+0*4] code works fine now. :red Sorry.

While I'm at it, how does 64-bit numbers work? Eg. if I've got a C function which returns a QWORD, where are the lower 32-bits located and the higher 32-bits?

donkey

Hi seb,

An even more legible way is to dereference using the structure definition, this will work in MASM and GoAsm, it may work in other assemblers as well...

INFO struct
        fr     DWORD   ?
        chs    DWORD   ?
        fl    DWORD   ?
        ct    DWORD   ?
        orr  DWORD   ?
        pl   DWORD   ?
INFO ends

;EBX contains a pointer to the structure in the DLL

mov eax, [EBX+INFO.chs]

; will yeild the same result as

mov eax,[EBX+1*4]

; but is much easier to read and understand


The reason this works is that a structure member resolves to an offset from the beginning of the structure, in your example INFO.fr resolves to 0, INFO.chs to 4 etc... The advantage to doing it this way is that you are no longer limited to 2,4,8 and 16 as the only multipliers you can use. For example if ct was a WORD value your method would fail while the method I demonstrated would have no problem and still execute faster as it uses immediates instead of a multiply.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Seb

Hi donkey,

thanks for you answer! I'll change it now and stick to your method in the future. :U

Regarding the 64-bit QWORD question, forget it, I found out about that, too. :bg

I do however have another question on stack: I've got a C function which returns a "float" value (REAL4 AFAIK). Now the problem here is that I need to convert that value into a DWORD and then set it as the maximum range for a slider. While I've got the slider stuff done, the FLD/FISTP code will not work no matter what I do - it either crashes or gives me an output of 1 which is totally incorrect. Does anyone have a hint here?

I'm trying to convert a piece of code in C to ASM, and this is what the C almost looks like (just so you get the general picture):


QWORD len=GetLength(handle);
DWORD len2=Convert(len); /* Convert() actually returns a float. */

...

donkey

Hi seb,

You can use the FPU to do your conversion, perhaps try moving it into a global variable first.

fld real4val
fistp dwordval
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Vortex

Seb,

This one also works :

mov eax,INFO.fr[edx]
mov ecx,INFO.chs[edx]

jdoe

Hi,

Instead of asking my question about structure syntax in a new topic I will use this one.
This topic show that sometimes there is more than one way to do something. My question is simple...

What is the difference between these... Are they all they same ?


OFNOTIFY STRUCT
   hdr       NMHDR <>
   hdr       NMHDR <?>
   hdr       NMHDR (<>)
   hdr       NMHDR (<?>)



Thanks

donkey

Hi jdoe,

As demonstrated by Vortex, MASM has alot of different syntax rules that are acceptable, this is true of any language as mature as MASM. Times change and a new ordering is added. In fact many of the examples you will see on this board are not even mentioned in my MASM manual. So to answer your question, yes, all of those examples are the same. The unfortunate thing is that some of the variations are not as clear, for example...

[EBX+INFO.fs]

Is very clear, it is evident from the line exactly what is happening; the offset of INFO.fs is added to the value in EBX. With Vortex's example you are left wondering whether the offset is multiplied by EBX because the general rule in algebra is that without an operator multiplication is implied...

xy = x*y

3xy= 3*x*y

INFO.fs[EBX]  = INFO.fs*EBX << this is actually wrong,  INFO.fs+EBX is actually the case

I have never liked that particular syntax in MASM and refrained from using it because it was not clear and the syntax was inconsistent with normal algebraic expressions.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

jdoe

Thanks for your reply donkey

Another way to access structure members, which is the one I use, and I find it very clear.


mov eax, [edx.INFO].fs
mov ecx, [edx.INFO].chs


:wink


Relvinian

Quote from: jdoe on November 20, 2006, 03:49:01 AM
Thanks for your reply donkey

Another way to access structure members, which is the one I use, and I find it very clear.


mov eax, [edx.INFO].fs
mov ecx, [edx.INFO].chs


:wink

I myself am close to this but do this instead.

mov eax, [edx].INFO.fs
mov ecx, [edx].INFO.chs


So many different ways to skin a cat. :-)

Relvinian