Macros to clear the local variables :
include LocalVarInit.inc
.data
string1 db 'y = %d , x = %d',0
INITLOC MACRO
VarSize=0
ENDM
LOCVAR MACRO _name,_type
VarSize=VarSize + SIZEOF(_type)
LastVar TEXTEQU _name
LOCAL _name : _type
ENDM
ENDLOC MACRO
lea eax,LastVar
invoke memfill,eax,VarSize,0
ENDM
.code
start:
call main
invoke ExitProcess,0
main PROC USES esi edi ebx
INITLOC
LOCVAR rc,RECT
LOCVAR x,DWORD
LOCVAR y,DWORD
ENDLOC
lea eax,rc
invoke printf,ADDR string1,y,x
ret
main ENDP
END start
Why not:
lea rcx,LastVar
mov RDX,VarSize
xor R8,R8
call memfill
or
push rdi
lea RDI,LastVar
mov RCX,VarSize
xor R8,R8
STOS(b/W/D/Q)
Because of that, I have always thought that the local variables would be better into a structure.
Hi Grincheux,
Thanks. Your code is for 64-bit while my version is for 32-bit coding. I will see what I can do.
Hi Grincheux,
Here is an attempt for the 64-bit code :
MessageBoxA PROTO :QWORD,:QWORD,:QWORD,:QWORD
MessageBox EQU <MessageBoxA>
ExitProcess PROTO :QWORD
printf PROTO :QWORD,:VARARG
memset PROTO :QWORD,:QWORD,:QWORD
INITLOC MACRO
VarSize=0
ENDM
LOCVAR MACRO _name,_type
VarSize = VarSize + SIZEOF(_type)
LastVar TEXTEQU _name
LOCAL _name : _type
ENDM
ENDLOC MACRO
mov rbx,rcx
lea rcx,LastVar
invoke memset,rcx,0,VarSize
mov rcx,rbx
ENDM
.data
string1 db 'x = %d , x = %d , z = %d',0
.code
start PROC PARMAREA=4*QWORD
call main
invoke ExitProcess,0
start ENDP
main PROC USES rsi rdi rbx PARMAREA=4*QWORD
INITLOC
LOCVAR x,QWORD
LOCVAR y,QWORD
LOCVAR z,QWORD
ENDLOC
mov x,1
mov y,2
mov z,3
invoke printf,ADDR string1,x,y,z
ret
main ENDP
QuoteMicrosoft Windows [version 10.0.17763.1577]
(c) 2018 Microsoft Corporation. Tous droits réservés.
C:\Users\Philippe\Downloads\Opera\StackTest>StackTest
x = 1 , x = 2 , z = 3
C:\Users\Philippe\Downloads\Opera\StackTest>
There is a bug, int the source it is
Quotemov x,1
mov y,2
mov z,3
invoke printf,ADDR string1,x,y,z
It's a joke! :P
That kind of macro is very useful.
If I pass a structure, I mut declare it as
LOCVAR MyStruct, Byte SIZEOF(_tagMYSTRUCT_)
Yes or no? Or do I have to define each item in a different LOCVAR
And to access one item it is X + 2 * sizeof(QWORD)?
It seems so easy when the code is written by you!
Could you replace the memset by a stos?
---------------------------------------I have an other question whis has niothing to see with this post.GoAsm allows to use variables declare in an other function/procCould it be possible to make this with PoAsmIs it dangerous or no?Thanks.
Hi Grincheux,
Now, the locals are cleared with the STOSQ statement :
ENDLOC MACRO
mov rbx,rcx
mov rcx,VarSize
lea rdi,LastVar
shr rcx,3 ; sizeof(QWORD) = 2^3
xor rax,rax
rep stosq
mov rcx,rbx
ENDM
Structures allocated as usually :
LONG TYPEDEF DWORD
RECT STRUCT
left LONG ?
top LONG ?
right LONG ?
bottom LONG ?
RECT ENDS
LOCVAR rc,RECT
LOCVAR x,QWORD
LOCVAR y,QWORD
LOCVAR z,QWORD
mov rc.left,4
mov rc.top,5
QuoteI have an other question whis has niothing to see with this post.
GoAsm allows to use variables declare in an other function/proc
Could it be possible to make this with PoAsm
Is it dangerous or no?
Hi Grincheux,
Could you post the GoAsm example?
You are the Assembler God.
I will post the example.
You cannot use the RBX and RDI registers in the macro without saving them before. Use R10 or R.. that are not reserved.
At the end it is possible to have LOCVARQ, LOCVARD, LOCVARW and LOCVARB with the equivalent STOSQ/D/W/B ot into the same MACRO if it can make the difference between the kind of variable.
Hello,
My example StackTest2b takes care of the nonvolatile registers :
main PROC USES rsi rdi rbx PARMAREA=4*QWORD
Macro edited to replace rbx with r10 :
ENDLOC MACRO
mov r10,rcx
mov rcx,VarSize
lea rdi,LastVar
shr rcx,3 ; sizeof(QWORD) = 2^3
xor rax,rax
rep stosq
mov rcx,r10
ENDM
QuoteAt the end it is possible to have LOCVARQ, LOCVARD, LOCVARW and LOCVARB with the equivalent STOSQ/D/W/B ot into the same MACRO if it can make the difference between the kind of variable.
Thin ice... You need to be sure that the stack is aligned to 16 bytes imposed by 64-bit coding.
I will rewrite my current program (myGimp) in assembly language, all this tools will help me.
It will be a hard work, but it is a nice challenge.
I have written this, if that can help you:
For 128 bits.
; **********************************************************************************
; ************************ ClearMem *************************************************
; **********************************************************************************
ALIGN 16
comment^
INPUT RCX = Pointer to destination
RDX = Number of bytes to copy
OUTPUT RAX = Source
^
PUBLIC ClearMem
ClearMem PROC __lpPointer:QWORD,__dwNumberOfBytes:DWORD PARMAREA=4*QWORD
xchg rdx,rcx
xor rax,rax
xorpd xmm0,xmm0
shufpd xmm0,xmm0,0
shr rcx,4
mov rax,16
jmp @ClearMem_Loop
ALIGN 16
@ClearMem_Loop :
movdqu [rdx],xmm0
add rdx,rax
dec rcx
jnz @ClearMem_Loop
ret
ClearMem ENDP
; **********************************************************************************
; *************************** F I N I S H E D ******************************************
; **********************************************************************************
END
Thank You
Hi Grincheux,
PUBLIC ClearMem
No need of this statement as procedures are visible to the external modules by default.
xchg rdx,rcx
You could remove this line. Redefining the procedure :
ClearMem PROC __dwNumberOfBytes:DWORD,__lpPointer:QWORD PARMAREA=4*QWORD
QuoteHi Grincheux,Could you post the GoAsm example?
I created a post "GoAsm".
A+
Oops the Pesky Paste Problem Prominently Prevails Providing Poor Posting Performance
John Z
This one of the many problem with this editor...