I literally started learning MASM32 yesterday so bear with me if this is a dumb question.
My understanding of addr
and offset
is as follows: both return the memory address of a variable but offset
only works on global variables (whose memory addresses are know at assemble time) and addr
will work on both global and local variables. I know what global and local variables are in higher level languages; my understanding is that variables declared in the .data
, .data?
, and .const
blocks are global and that variable declared with the local
keyword inside of procedures are local.
My entire code is:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
.data
szCap db "Hello", 0 ;caption for the MessageBox
szMsg db "Hello, world!", 0 ;text for the MessageBox
.code
;Procedure for creating a MessaheBox with NULL parent and variable text
TestProcedure proc msg:dword, cap:dword
invoke MessageBox, NULL, msg, cap, MB_OK
ret
TestProcedure endp
main:
; error on these lines
push addr szCap ; C:\masm32\My files\HelloWorld.asm(35) : error A2008: syntax error : addr
push addr szMsg ; C:\masm32\My files\HelloWorld.asm(36) : error A2008: syntax error : addr
call TestProcedure
invoke ExitProcess, 0
end main
However, if I change addr
to offset
, the code works perfectly. Why does addr
fail to assemble in this instance?
In flat mode, all addresses are offsets.
The ADDR operator was added in a fairly recent version of MASM and as far as I understand is used exclusively with the INVOKE keyword. In an INVOKE, ADDR does the same as offset for global identifiers but can calculate the relative address of a local, stack-based variable as well (where it would typically emit an LEA instruction).