I think i must have missed something, but it seems i cannot get it to work...
Suppose i have a macro, which does different things to it´s argument. If it´s a number - do this, if it´s text - do that.
test macro arg:req
local r$, c$
r$ TEXTEQU <>
r$ catstr r$, <arg> ;stringize arg
c$ SUBSTR r$, 1, 1
ifidn c$,<0>
; process number
else
; process text
endif
endm
"ifidn c$,<0> tells me, if the first character is "0". But how could i tell, if it´s in the range from "0" to "9" in one line. I want to avoid a lot of "elseifidn" branches.
JK
in masm32\macros\macros.asm
you have a set of macros who can help you,this one in particular:
Quote
; -------------------------
; determine an operand type
; -------------------------
op_type MACRO arg:REQ
LOCAL result
result = opattr(arg)
IF result eq 37 ;; label, either local or global
EXITM %1
ELSEIF result eq 42 ;; GLOBAL var
EXITM %2
ELSEIF result eq 98 ;; LOCAL var
EXITM %3
ELSEIF result eq 36 ;; immediate operand or constant
EXITM %4
ELSEIF result eq 48 ;; register
EXITM %5
ELSEIF result eq 805 ;; local procedure in code
EXITM %6
ELSEIF result eq 933 ;; external procedure or API call
EXITM %7
ENDIF
EXITM %0 ;; anything else
ENDM
; *************************************
; Return a register size in BYTES or *
; 0 if the argument is not a register *
; *************************************
regsize MACRO item
LOCAL rval,ln
rval = 0
ln SIZESTR <item>
IF ln EQ 2
goto two
ELSEIF ln EQ 3
goto three
ELSEIF ln EQ 4
goto four
ELSEIF ln EQ 5
goto five
ELSEIF ln EQ 6
goto six
ELSEIF ln EQ 8
goto eight
ELSE
goto notreg
ENDIF
:two
for arg,<al,ah,bl,bh,cl,ch,dl,dh>
IFIDNI <arg>,<item>
rval = 1
EXITM
ENDIF
ENDM
IF rval NE 0
EXITM %rval
ENDIF
for arg,<ax,bx,cx,dx,sp,bp,si,di>
IFIDNI <arg>,<item>
rval = 2
EXITM
ENDIF
ENDM
IF rval NE 0
EXITM %rval
ENDIF
goto notreg
:three
for arg,<eax,ebx,ecx,edx,esp,ebp,esi,edi>
IFIDNI <arg>,<item>
rval = 4
EXITM
ENDIF
ENDM
IF rval NE 0
EXITM %rval
ENDIF
for arg,<st0,st1,st2,st3,st4,st5,st6,st7>
IFIDNI <arg>,<item>
rval = 10
EXITM
ENDIF
ENDM
IF rval NE 0
EXITM %rval
ENDIF
for arg,<mm0,mm1,mm2,mm3,mm4,mm5,mm6,mm7>
IFIDNI <arg>,<item>
rval = 8
EXITM
ENDIF
ENDM
IF rval NE 0
EXITM %rval
ENDIF
goto notreg
:four
for arg,<xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7>
IFIDNI <arg>,<item>
rval = 16
EXITM
ENDIF
ENDM
IF rval NE 0
EXITM %rval
ENDIF
goto notreg
:five
for arg,<mm(0),mm(1),mm(2),mm(3),mm(4),mm(5),mm(6),mm(7)>
IFIDNI <arg>,<item>
rval = 8
EXITM
ENDIF
ENDM
IF rval NE 0
EXITM %rval
ENDIF
for arg,<st(0),st(1),st(2),st(3),st(4),st(5),st(6),st(7)>
IFIDNI <arg>,<item>
rval = 10
EXITM
ENDIF
ENDM
IF rval NE 0
EXITM %rval
ENDIF
goto notreg
:six
for arg,<xmm(0),xmm(1),xmm(2),xmm(3),xmm(4),xmm(5),xmm(6),xmm(7)>
IFIDNI <arg>,<item>
rval = 16
EXITM
ENDIF
ENDM
IF rval NE 0
EXITM %rval
ENDIF
:eight
for arg,<edx::eax,ecx::ebx>
IFIDNI <arg>,<item>
rval = 8
EXITM
ENDIF
ENDM
IF rval NE 0
EXITM %rval
ENDIF
:notreg
EXITM %rval
ENDM
;---------------------------------------------------
here the informations you find in msdn
Quote
OPATTR, opérateur
08/01/2020 • 2 minutes to read • Edit Online
Syntaxe
Voiraussi
Retourne un mot définissant le modeet la portée del' expression.L'octet de poids faibleest identiqueà l'octet
retourné par .TAPEZ.L'octet de poids fort contient des informations supplémentaires.
Expression opattr,
Informations deréférencesur les opé
It is in french!,you lose nothing...very cool and very short
To test the numbers returned by opattr,use ECHO or %ECHO
Thanks, i see, i can use opattr. A result of 36 indicates an immediate value or a constant. This might solve my problem, but it doesn´t answer the original question: How could i make a comparison to a range of charcters in one single line ?
Ok, i found a good solution. I could use another macro: "if is_number(arg) eq 1" ..., where is_number returns <1>, if arg is a number. Inside is_number multiple if, elseif would be necessary, but in the main macro it´s only one line - exactly, what i wanted.
include \masm32\include\masm32rt.inc
testme macro arg:req
local c$, ins
c$ SUBSTR <arg>, 1, 1
ins INSTR <0123456789>, c$
if ins
% echo arg is a number
else
% echo arg is not a number
endif
endm
.code
start:
testme 1
testme eax
testme 9
inkey "ok"
exit
.err ; for testing: don't let it succeed, we just want to see the echos
end start
Since test is an instruction and therefore cannot be used as a macro name, it means that you didn't test your own macro before asking for help. That won't get you very far :cool:
Hi jj2007,
thanks for your solution! You are right, the code i supplied was pseudo code just for demonstrating the problem. It´s kind of a reduced to the minimum version of what i was working with. Thanks again.
JK
added: currently my code has more than 2000 lines, a bit too much for demonstrating a specific problem ...