I'm hoping someone can pointer me in the right direction....
I receive a pointer (in lParam) from a windows message that points to a structure. I need to look at a member of that structure. I've tried the following, but get 'invalid instruction operands'. Should I be using LEA instead of MOV?
The structure:
DEV_BROADCAST_HDR STRUCT
dbch_size DWORD ?
dbch_devicetype DWORD ?
dbch_reserved DWORD ?
DEV_BROADCAST_HDR EndS
DlgProc extract:
...
local devHeader:DEV_BROADCAST_HDR
...
.elseif eax == DBT_DEVICETYPESPECIFIC
mov eax, lParam
mov devHeader,[eax] ; break occurs here!
mov eax, devHeader.dbch_devicetype
.if eax == 00000005h
invoke MessageBox,hWin,addr szDevice,addr szAppName, MB_OK
.endif
.else
...
George,
You are having problems because its a LOCAL and you would normally use LEA to load the address of a local. With an invoke call you just use ADDR YourStruct.
Thing is, the structure is not being filled from an INVOKE, it gets filled by the windows message that sends it (in this case WM_DEVICECHANGE).
uMsg = WM_DEVICECHANGE
wParam = DBT_DEVICETYPESPECIFIC
lParam = [i]pointer to structure[/i]
How would I read a member from that structure that was filled by the windows message? Or have I missed the plot completely?
Hutch, I was missing the plot. Thanks for your assistance!
Quote from: hutch-- on June 29, 2005, 01:38:35 PM
George,
You are having problems because its a LOCAL and you would normally use LEA to load the address of a local. With an invoke call you just use ADDR YourStruct.
No, the problem is that he is doing mov devHeader,[eax] which is an illegal mov mem,mem.
But why make the devHeader in the first place? It would be simpler just to assume eax to the appropriate stuct and use it as a pointer.
PUsh dword ptr[eax]
pop devHeader
Try to change it with this.
No because devHeadr is not a dword in size. It is a whole structure :boohoo:
will this not work?
mov eax, lParam
lea eax,devHeader
mov eax, devHeader.dbch_devicetype
.if eax == 00000005h
invoke MessageBox,hWin,addr szDevice,addr szAppName, MB_RETRYCANCEL
.else
...
.endif
mov eax,lParam
lea eax,devHeader
mov eax,devHeader.dbch_devicetype
That will not work. First, you have to understand where the structure actually is. In your code, there are two structures: one is in memory somewhere and the pointer to it is in lParam. The other is on the stack. The first one has correct information, the second has random information. Obviously you want the correct information, so you use lParam as a pointer to the correct structure.
mov eax,lParam
assume eax:ptr DEV_BROADCAST_HDR
mov edx,[eax].dbch_devicetype
assume eax:nothing
.if edx == 05h
...
Thanks AeroASM, I'll give this a try!
Hi georgek01,
If, like me, you prefer not to use the ASSUME directive. MASM offers a number of other ways to access the data in a structure passed as a pointer. As AeroASM said, you are passed a pointer to a memory location where the data you are interested in is located and a simple DWORD mov will not work, and is not very efficient as you are just moving the information around. I prefer this method both in GoAsm and MASM (you do not need the local declaration in any case)
[REG32+Structure.element]
mov edi, [lParam]
mov eax, [edi+DEV_BROADCAST_HDR.dbch_size]
mov eax, [edi+DEV_BROADCAST_HDR.dbch_devicetype]
mov eax, [edi+DEV_BROADCAST_HDR.dbch_reserved]
Alternatively in MASM (though the above is clearer and works as well)
mov eax, [edi.DEV_BROADCAST_HDR.dbch_size]
In this case the [edi+DEV_BROADCAST_HDR.dbch_size] allows you to directly manipulate the data without ASSUME or moving it.
Remember, ASSUME makes an ASS out of U and ME :bg
Thanks donkey. It's nice to have options! I'll try your suggestion too.