I would like to test if the <Arg>ument of a macro is a register.
I wrote :
MUL_BY_45 MACRO Arg:REQ
IF( (OPATTR(Arg)AND 4) EQ 0)
lea Arg,[Arg + 8 * Arg]
lea Arg,[Arg + 4 * Arg]
ELSE
.ERR <Invalid Argument>
EXITM
ENDM
The result always is <Invalid Argument>
I never use the macros for once I need them I am blocked.
Please help me
Little test...
include \masm32\include\masm32rt.inc
.686p
.xmm
MUL_BY_45 MACRO Arg:REQ
LOCAL oa, tmp$
oa = (opattr Arg) AND 127
tmp$ CATSTR <arg >, <Arg>, < is >, %oa
% echo tmp$
; IF( (OPATTR(Arg)AND 4) EQ 0)
; lea Arg,[Arg + 8 * Arg]
; lea Arg,[Arg + 4 * Arg]
; ELSE
; .ERR <Invalid Argument>
; ENDIF
EXITM
ENDM
.data
somevar dd ?
.code
start:
MUL_BY_45 123
MUL_BY_45 eax
MUL_BY_45 xmm0
MUL_BY_45 somevar
MUL_BY_45 offset somevar
.err
exit
end start
You don't compute anything.
The argument must be a register, because of LEA
If it is not a register it must return the error message
Quote from: Grincheux on December 02, 2015, 11:37:05 PM
You don't compute anything.
If, instead of asking for spoonfeeding, you would have built the example, you would have seen this in your output window:
arg 123 is 36
arg eax is 48
arg XMM(0) is 48
arg somevar is 42
arg offset somevar is 38
To make it even clearer, here the binary presentation:
00000000000000000000000000100100
10987654321098765432109876543210 123
00000000000000000000000000110000 eax
00000000000000000000000000101010 globalvar
00000000000000000000000000100110 offset globalvar
00000000000000000000000001100010 localvarWho told you that
and 4 yields registers?
Masm manual
Quote
OPATTR/.TYPE Return Value
Bit(s) Meaning
0 References a label in the code segment if set.
1 References a memory variable or relocatable data object if set.
2 Is an immediate (absolute/constant) value if set.
3 Uses direct memory addressing if set.
4 Is a register name, if set.
5 References no undefined symbols and there is no error, if set.
6 Is an SS: relative reference, if set.
7 References an external name.
8-10 000 - no language type
001 - C/C++ language type
010 - SYSCALL language type
011 - STDCALL language type
100 - Pascal language type
101 - FORTRAN language type
110 - BASIC language type
In fact 48 is the fourth bit not the value 4
MUL_BY_100 MACRO Arg:REQ
Temp = OPATTR(Arg)
IF(Temp EQ 48)
push ecx
mov ecx,Arg ;; Suppose EAX = 10 & ECX = 10
lea Arg,[ecx + 4 * ecx] ;; EAX = ECX + (4 * ECX) = 10 + (4 * 10) = 10 + 40 = 50
lea Arg,[Arg + 4 * Arg] ;; EAX = EAX + (4 * EAX) = 50 + (4 * 50) = 50 + 200 = 250
shl Arg,2 ;; EAX = EAX * 4 = 250 * 4 = 1000
pop ecx
ELSE
.ERR <Invalid argument parameter, not a register>
ENDIF
ENDM
IF(OPATTR(Arg) EQ 48) does not work we need to have a variable 'Temp'
Hi Grincheux, instead of Temp use this syntax:
IF (OPATTR arg) EQ 48
MUL_BY_100 MACRO Arg:REQ, redx:=<edx>
IF (OPATTR Arg) EQ 48
IFIDN <Arg>,<edx>
.ERR <EDX register value would be overwritten by macro>
EXITM
ENDIF
IFIDN <Arg>,<EDX>
.ERR <EDX register value would be overwritten by macro>
EXITM
ENDIF
push redx
mov redx,Arg ;; Suppose EAX = 10 & ECX = 10
lea Arg,[redx + 4 * redx] ;; EAX = ECX + (4 * ECX) = 10 + (4 * 10) = 10 + 40 = 50
lea Arg,[Arg + 4 * Arg] ;; EAX = EAX + (4 * EAX) = 50 + (4 * 50) = 50 + 200 = 250
shl Arg,2 ;; EAX = EAX * 4 = 250 * 4 = 1000
pop redx
Echo *** MUL_BY_100 : Result in Arg ***
ELSE
.ERR <Invalid argument parameter, not a register>
ENDIF
ENDM
In fact when
IFIDN <Arg>,<edx>
.ERR <EDX register value would be overwritten by macro>
EXITM
ENDIF
Initially redx is equal to EDX
I would like to replace redx by ecx
And I would like to uppercase the Arg.
Because eax != EAX
The goal would be to replace use ECX when EDX is the Arg and EDX when ECX is the Arg. For this reason I use REDX
I could use a local variable but if we are not in a PROC statment, a label for example, I cant do it.