News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Pointer to a structure

Started by sys64738, October 16, 2013, 05:39:59 AM

Previous topic - Next topic

sys64738

I have a data structure which looks like this:

USERNAME_LENGTH equ 1fh

RegistrationRecord UNION
RecordSize db 512
STRUCT
  UserName db USERNAME_LENGTH+1 ; User name
  Buffersize dd ? ; Member count in array
  Checksum dd ? ;
ENDS
RegistrationRecord ENDS


In the asm file I declare it like as a pointer:

.Data?
gRecord dd RegistrationRecord
   also tried variations
gRecord dd:RegistrationRecord
gRecord dd: PTR RegistrationRecord


But when I try to invoke a function using a member, it doesn't work.


invoke SendMessage, UserCtrl, WM_GETTEXTLENGTH, USERNAME_LENGTH, ADDR gRecord.UserName


Results in:

error A2006:undefined symbol : UserName


I tried to look in the examples, but I don't seem to find an example which uses a struct pointer as a global variable.

sys64738

I found now a solution that works:


mov eax, gRecord
assume eax:ptr RegistrationRecord
invoke SendMessage, UserCtrl, WM_GETTEXTLENGTH, USERNAME_LENGTH, ADDR [eax].UserName
assume eax:nothing


But I wonder if it isn't possible to use the adress directly instead of having to load it into eax and do the assume thing.

dedndave

maybe you want something like this
i'm not really sure exactly what you are after with the 512 and union thing   :P

USERNAME_LENGTH EQU 1Fh
REG_BUFFER_SIZE EQU 512-(USERNAME_LENGTH+1)-(2*sizeof DWORD)

RegistrationRecord STRUCT
  szUserName         db USERNAME_LENGTH+1 dup(?)
  nBufferSize        dd ?
  dwCheckSum         dd ?
  Buffer             db REG_BUFFER_SIZE dup(?)
RegistrationRecord ENDS

    .DATA?

RegRcd RegistrationRecord <>

    .CODE

    mov     eax,RegRcd.nBufferSize
;
;
;
    mov     esi,offset RegRcd
    mov     eax,[esi].RegistrationRecord.nBufferSize
;
;
;
    ASSUME  ESI:Ptr RegistrationRecord

    mov     eax,[esi].nBufferSize

    ASSUME  ESI:Nothing

jj2007

Looks as if you should study the dup(?) operator:

RegistrationRecord UNION
  RecordSize        db 512 dup(?)
  STRUCT
        UserName        db USERNAME_LENGTH+1 dup(?)                        ; User name
        Buffersize        dd ?                        ; Member count in array
        Checksum        dd ?                        ;
  ENDS
RegistrationRecord ENDS

.data?
UserCtrl        dd ?
gRecord        RegistrationRecord <>

.code
  invoke SendMessage, UserCtrl, WM_GETTEXTLENGTH, USERNAME_LENGTH, ADDR gRecord.UserName

sys64738

Quote from: jj2007 on October 16, 2013, 06:57:27 AM
Looks as if you should study the dup(?) operator:

Yes, I noticed, that I don't really have a clue what the dup really means. One thing after the other. :) But I will read the link right after.


Quote
.data?
UserCtrl        dd ?
gRecord        RegistrationRecord <>

I'm a bit confused about this now. I thought that using the "<>" reserves space for the structure itself, while I only want to store a pointer there of the type RegistrationRecord.

Somethign like this:

gRecordStruct RegistrationRecord <>
gRecord  dd ?     ; Here I have the pointer but of unspecified type, right?

mov   eax, ADDR gRecordStruct
mov  gRecord, eax


In this example the pointer is unspecified. I know that in assembly the type checking is probably not so strict like on higher languages, but I wonder if in case of an invoke the assembler can raise an error if the type is given and doesn't match?

Or is this irrelevant in assembly and the type doesn't matter at all, except as a documentation in the source? Because I noticed in the examples, that they usually only do

   ptr dd ?
or
   ptr dd 0


Without giving any type.

sys64738

Quote from: dedndave on October 16, 2013, 06:03:37 AM
maybe you want something like this
i'm not really sure exactly what you are after with the 512 and union thing   :P

Maybe I think to much in C. :) The Union ensures that the whole record structure is exactly 512 bytes long, even if there are some mebers which are not used yet. If I put only a struct with my members it is currently 40 bytes and I have to keep in mind that, when I pass it around, I may not pass only 40 bytes, but 512. So the union is the placeholder for the total size. Otherwise I would have to do what you showed in your example:

USERNAME_LENGTH EQU 1Fh
REG_BUFFER_SIZE EQU 512-(USERNAME_LENGTH+1)-(2*sizeof DWORD)


So I have to list all membersizes manually. Currently the structure is simple enough, but if there are new memebers added, you always would have to adjust it.


dedndave

well - that's ok, too
if you want to create a UNION - no problem

some good examples from windows.inc...
CHARTYPE UNION
UnicodeChar    WORD ?
AsciiChar      db ?
CHARTYPE ENDS

CHAR_INFO STRUCT
  Char          CHARTYPE <>
  Attributes    WORD      ?
CHAR_INFO ENDS

MOUSE_EVENT_RECORD STRUCT
  dwMousePosition       COORD <>
  dwButtonState         DWORD      ?
  dwControlKeyState     DWORD      ?
  dwEventFlags          DWORD      ?
MOUSE_EVENT_RECORD ENDS

KEY_EVENT_RECORD STRUCT
  bKeyDown          DWORD ?
  wRepeatCount      WORD ?
  wVirtualKeyCode   WORD ?
  wVirtualScanCode  WORD ?
  UNION
    UnicodeChar     WORD ?
    AsciiChar       BYTE ?
  ENDS
  dwControlKeyState DWORD ?
KEY_EVENT_RECORD ENDS

WINDOW_BUFFER_SIZE_RECORD STRUCT
  dwSize  COORD <>
WINDOW_BUFFER_SIZE_RECORD ENDS

MENU_EVENT_RECORD STRUCT
  dwCommandId  DWORD      ?
MENU_EVENT_RECORD ENDS

FOCUS_EVENT_RECORD STRUCT
  bSetFocus  DWORD      ?
FOCUS_EVENT_RECORD ENDS

INPUT_RECORD STRUCT
  EventType             WORD ?
  two_byte_alignment    WORD ?
  UNION
    KeyEvent                KEY_EVENT_RECORD            <>
    MouseEvent              MOUSE_EVENT_RECORD          <>
    WindowBufferSizeEvent   WINDOW_BUFFER_SIZE_RECORD   <>
    MenuEvent               MENU_EVENT_RECORD           <>
    FocusEvent              FOCUS_EVENT_RECORD          <>
  ENDS
INPUT_RECORD ENDS