Hi all!
I found not justified to use freg (Pseudo push/pop registers in 64 bits) (http://masm32.com/board/index.php?topic=9267.0) for very simple pieces of code.
For simple code minusculus macros can do the job. Beside push and pop, others operations like addition or multiplication between a pointer and a dword requiere duality.
For example this 32 bit code:
Foo proc
···
push edx
add edx, d1 ; d1 is dword
invoke St0ToStr, edx, 0, 4, f_NOR
fstp st(0)
mov x1, $invoke(StrLength, addr Row)
pop edx
···
push [ecx+0]
push [ecx+4]
mov edx, [edi].pData
pop [edx+eax+4]
pop [edx+eax+0]
···
ret
Foo endp
become 32/64 bit code:
Foo2 proc
x_preservation .xdx, QWORD
x_preservation .reg1, DWORD
x_preservation .reg2, DWORD
···
x_pushr xdx, .xdx
xd_add xdx, d1 ; d1 is dword
invoke St0ToStr, xdx, 0, 4, f_NOR
fstp st(0)
mov x1, $invoke(StrLength, addr Row)
x_popr xdx, .xdx
···
x_pushv [xcx+0], .reg1, r10d
x_pushv [xcx+4], .reg2, r10d
mov xdx, [xdi].pData
x_popv [xdx+xax+4], .reg2, r10d
x_popv [xdx+xax+0], .reg1, r10d
···
ret
Foo2 endp
So far this macros were enough for me:
x_preservation macro n_var, xtype
if TARGET_BITNESS eq 32
else
local &n_var : &xtype
endif
endm
x_pushr macro arg1, n_var
if TARGET_BITNESS eq 32
push &arg1
else
mov &n_var, &arg1
endif
endm
x_popr macro arg1, n_var
if TARGET_BITNESS eq 32
pop &arg1
else
mov &arg1, &n_var
endif
endm
x_pushv macro arg1, n_var, auxreg
if TARGET_BITNESS eq 32
push arg1
else
mov &auxreg, &arg1
mov &n_var, &auxreg
endif
endm
x_popv macro arg1, n_var, auxreg
if TARGET_BITNESS eq 32
pop arg1
else
mov &auxreg, &n_var
mov &arg1, &auxreg
endif
endm
xd_add macro x_reg, d_var
if TARGET_BITNESS eq 32
add &x_reg, &d_var
else
mov r10d, &d_var
add &x_reg, r10
endif
endm
xd_mul macro d_var
if TARGET_BITNESS eq 32
mul &d_var
else
mov r10d, &d_var
imul xax, r10
endif
endm
Regards, HSE