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.
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.
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
Looks as if you should study the dup(?) operator: (http://www.sourceformat.com/standard/asm-coding-standard-assembly-8.htm)
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
Quote from: jj2007 on October 16, 2013, 06:57:27 AM
Looks as if you should study the dup(?) operator: (http://www.sourceformat.com/standard/asm-coding-standard-assembly-8.htm)
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.
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.
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