I'm trying to fill in a WAVEHDR structure, but the compiler keeps complaining about error A2070: invalid instruction operands
.data?
m_WaveHeader WAVEHDR <>
m_Data db 1024 dup (?)
.code
mov m_WaveHeader.lpData, m_Data ; error A2070
;mov m_WaveHeader.lpData, [m_Data] ; just to test if this works
Trying to load the address of m_Data into a register first and then place this address
into lpData didn't solve it either.
I cannot figure out whats wrong here. Can abybody point me in the right direction?
Just Looking at your code and comparing to something i use
.data?
m_WaveHeader WAVEHDR <>
m_Data db 1024 dup (?)
Should the m_Data be an equ like MAX_PATH
below or under .data and not .data? because
you are dealing with byte data
and should
m_WaveHeader WAVEHDR <>
be
m_WaveHeader WAVEHDR <?>
under .data? as you have it
###########################
.const
MAX_PATH equ 260
FIND_DATA STRUCT
dwFileAttributes DWORD ?
ftCreationTime FILETIME <>
ftLastAccessTime FILETIME <>
ftLastWriteTime FILETIME <>
nFileSizeHigh DWORD ?
nFileSizeLow DWORD ?
dwReserved0 DWORD ?
dwReserved1 DWORD ?
cFileName BYTE MAX_PATH dup(?)
cAlternate BYTE 14 dup(?)
FIND_DATA ENDS
If you get something out of this great if not i give you a full example.
Also should you be moving the data into a register or something
mov m_WaveHeader.lpData
should be
mov eax, m_WaveHeader.lpData
What you appear to be trying to do is put the address of m_Data into the lpData member of m_WaveHeader. To do this, you'll either need to use the OFFSET operator or the LEA instruction:
lea eax, m_Data
mov m_WaveHeader.lpData, eax
or
mov m_WaveHeader.lpData, OFFSET m_Data
The advantage of the first one is that it will work on local variables as well as global ones. The disadvantage is that it requires an extra instruction and a register. This is the code that gets assembled when you use the 'ADDR' operator in INVOKE statements (which is why you can't use ADDR and EAX in the same statement :wink )
The second one will only work for variables defined in a segments (as yours are) and not as LOCALs, ie. the assembler needs to be able to determine the address at compile time which it can't for variables stored on the stack. On the plus side, it assembles to an immediate, so you can move it straight into a memory location (ie. you don't need to go via a register).
To answer ic2's query, the difference between .data and .data? is that the first one is initialised and stored in the executable, so defining a 1024 byte array in the .data section will add 1024 bytes to the .exe file, while the second is allocated when the process starts, so defining large arrays here don't increase the size of the executable. However, the initial values of variables in the .data? section are not defined and should be initialised at run time. IIRC, structures defined with the <> notation don't require a question mark, but it's easy enough to fix if it doesn't compile :wink
Cheers,
Zooba :U
mov eax, m_Data
mov m_WaveHeader.lpData, eax
Paul
The code as specified by Zooba worked :cheekygreen:.
I have tried something similar before, but can't remember exactly what, I've must have done something wrong here.