This is a macro that provides an efficient way to fill an area of memory with individual variables. For example,
Quotedw2mem offset buffer, 1, 2, 3, eax, ebx, offset AppName, 100, 101, 102, 1000, 1001, 1002
writes the dwords 1, 2, 3, eax, ... 1002 to the address "buffer". The overhead is a mere 4 bytes.
include \masm32\include\masm32rt.inc
dw2mem MACRO dest, args:VARARG
LOCAL ct, oa, arglist, fm$
ct=0
arglist equ < >
FOR arg, <args>
ct=ct+1
arglist CATSTR <arg>, </>, arglist
ENDM
push ebp
mov ebp, esp
oa = (opattr dest) AND 127
if oa eq 38 ; immediate mem
mov esp, dest+4*ct
elseif oa eq 48 ; reg
lea esp, [dest+4*ct]
else
mov esp, dest
add esp, 4*ct
endif
REPEAT ct
is INSTR arglist, </>
fm$ SUBSTR arglist, 1, is-1
push fm$
arglist SUBSTR arglist, is+1
ENDM
leave
ENDM
.data
TheBuf dd buffer
buffer dd ?
arg2 dd ?
arg3 dd ?
arg4 dd ?
arg5 dd ?
arg6 dd ?
moreargs dd 20 dup(?)
.code
AppName db "Stack difference:", 0
start: mov ebx, esp
mov eax, offset buffer
dw2mem offset buffer, 1, 2, 3, eax, ebx, offset AppName, 100, 101, 102, 1000, 1001, 1002
mov eax, offset buffer
dw2mem eax, 1, 2, 3, eax, ebx, offset AppName
dw2mem TheBuf, 1, 2, 3, eax, ebx, offset AppName
sub ebx, esp
MsgBox 0, str$(ebx), arg6, MB_OK
exit
end start
dw2mem offset buffer, 1, 2, 3, eax, ebx, offset AppName, 100, 101, 102, 1000, 1001, 1002
translates to
push ebp
xchg esp, ebp
mov esp, 00402034
push 3EA
push 3E9
push 3E8 ; 1000
push 66
push 65
push 64
push 00401001 ; offset AppName
push ebx
push eax
push 3
push 2
push 1
leave
(remember
leave is the equivalent of
mov esp, ebp
pop ebp
normally used to set frames)