By "one's own macros" I mean this sort of thing:
@call MACRO WhatToCall,r1,v1,r2,v2,r3,v3,r4,v4,r5,v5,r6,v6
@mov r1,v1,r2,v2,r3,v3,r4,v4,r5,v5,r6,v6
call WhatToCall
ENDM
@mov MACRO m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12
@MovOrXor m1,m2
@MovOrXor m3,m4
@MovOrXor m5,m6
@MovOrXor m7,m8
@MovOrXor m9,m10
@MovOrXor m11,m12
ENDM
@MovOrXor MACRO m1,m2 ;internal
ifnb
if (.type (m1)) and 10h ;register
ifidn ,<0>
bytereg instr <"ahalbhblchcldhdlAHALBHBLCHCLDHDL">,
if bytereg
mov m1,0
else
xor m1,m1
endif
else
mov m1,m2
endif
else
mov m1,m2
endif
endif
ENDM
You can do the same sort of thing for push and pop instead of mov. Such "helper macros" serve to enlarge the list of conventional mnemonics, among other things.
Larry, if you like that kind of stuff, give this a try:
mv MACRO M1, M2, M3
IFIDN ,
ECHO MACRO Warning:mv:M1=M2 Move ignored.
ELSE
IF (OPATTR (M2)) AND 00010000y ;; source is a register
mov M1,M2
ELSEIF (OPATTR (M2)) AND 00000100y ;; source is constant
IF M2 EQ 0
IF (OPATTR (M1)) AND 00010000y ;; destination is register
xor M1,M1
ELSE
and M1,0
ENDIF
ELSEIF M2 EQ -1
or M1,-1
ELSE
mov M1,M2
ENDIF
ELSE ;; source is memory
IF (OPATTR (M1)) AND 00010000y ;; destination is a register
mov M1,M2
ELSE
IF (OPATTR (M3)) AND 00010000y
mov M3,M2
mov M1,M3
ELSE ;; try to make an object file anyway
ECHO MACRO Warning:mv:M3 should be a register.
push M2
pop M1
ENDIF
ENDIF
ENDIF
ENDIF
ENDM
@mov MACRO args:VARARG
LOCAL m2, mX
mX = 0
FOR m1,
IFE mX
m2 EQU m1
mX = -1
ELSE
% mv m2, m1
mX = 0
ENDIF
ENDM
ENDM
:D:cool::D Work it like:
.DATA
xxx dd 1234
xxy dd 5678
xxz dd 0789
.CODE
@mov eax, 0, ecx, xxx, edx, ecx, esi, -1, xxy, xxz, xxz, -1
mv xxx,xxy,eax