News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Question about MACROs

Started by CCurl, October 13, 2015, 05:10:47 PM

Previous topic - Next topic

CCurl

I'm a newbie, so there is probably a much better way to do what I am trying to do, but I am curious why it is complaining about this MACRO usage ...

..
   codeStart  EQU 1024
   hereADDR   EQU    1*4

   theMemory DWORD ?

; -------------------------------------------------------------------------
memRef MACRO addr1:REQ
   mov ebx, theMemory
   add ebx, addr1
ENDM
; -------------------------------------------------------------------------
memSet MACRO addr1:REQ, val
   memRef addr1
   mov [ebx], val
ENDM
; -------------------------------------------------------------------------

   invoke GlobalAlloc, GMEM_ZEROINIT, memorySize
   mov theMemory, eax

this doesn't work (see the error below) ...
   
   memSet hereADDR, codeStart

but this works .. why?
   
   mov eax, codeStart
   memSet hereADDR, eax

The error is this:

forth.asm(178) : error A2070:invalid instruction operands
memSet(2): Macro Called From
  forth.asm(178): Main Line Code

jj2007

Try memSet hereADDR, offset codeStart

Can't test it because you didn't post a complete snippet.

rrr314159

Quote from: CCurlthis doesn't work (see the error below) ...
   
   memSet hereADDR, codeStart

but this works .. why?
   
   mov eax, codeStart
   memSet hereADDR, eax

- The first statement gives rise to (via the macros)

mov [ebx], codeStart

- this is invalid because you're trying to mov from memory to memory - no good. [ebx], BTW, may look like a "register" but it's a reference to memory, the value pointed at by ebx. And codeStart refers to the value (in memory) pointed at by the label codeStart (which, u know, is just a number: an address)

- So either you actually want to mov the address of CodeStart into [ebx], in which case follow jj's advice:

memSet hereADDR, offset codeStart

- which produces the statement

mov [ebx], offset codeStart ; legal because the 2nd term is an immediate value: a fixed number

- or else you want the value in memory at the label codeStart, so you have to write the two statements given (by OP):
mov eax, codeStart
memSet hereADDR, eax


- which leads to

mov [ebx], eax ; legal, 2nd term is register

- In that case u may want to change the macro:

; -------------------------------------------------------------------------
memSet MACRO addr1:REQ, val
   memRef addr1
   mov eax, val
   mov [ebx], eax
ENDM
; -------------------------------------------------------------------------


- the only problem, now you're using ("trashing") eax. Instead you can write

; -------------------------------------------------------------------------
memSet MACRO addr1:REQ, val
   memRef addr1
   push val
   pop [ebx]
ENDM
; -------------------------------------------------------------------------


- There's a macro (from macros.asm) which does the last two statements, "m2m" so you can write

; -------------------------------------------------------------------------
memSet MACRO addr1:REQ, val
   memRef addr1
   m2m [ebx], val
ENDM
; -------------------------------------------------------------------------


- Without looking at the rest of your code, that's probably what you want to do
I am NaN ;)

CCurl

Thanks guys! Tricks of the trade are always good.