Reputation: 109
This might be a bit of a stupid syntax question, but is there a way you can make conditional jumps based on variable type? I'm trying to write a macro (for a class) that can take a byte, word, or double word as an argument and write it to the screen.
mWriteInt MACRO integer:REQ
;cmp integer, DWORD
;je dwordOp
movsx eax, word ptr integer
call WriteInt
mov edx, OFFSET endl
call WriteString
; for a DWORD
; dwordOp:
ENDM
So basically, the code executed should be different based on what type of variable is passed to the macro. No matter how I try to execute this, I get compiler errors.
I've tried:
cmp integer, DWORD
cmp TYPE integer, DWORD
and I don't really know where to go from here. I've looked in every reference I can think of, but it doesn't seem to be a common thing
Edit:
mWriteInt MACRO integer:REQ
IF (TYPE integer EQ TYPE DWORD)
call WriteInt
ENDIF
IF (TYPE integer EQ TYPE BYTE)
call WriteInt
ENDIF
IF (TYPE integer EQ TYPE WORD)
movsx eax, word ptr integer
call WriteInt
ENDIF
mov edx, OFFSET endl
call WriteString
ENDM
Upvotes: 4
Views: 1466
Reputation: 29022
In MASM there is the OPATTR
operator. Quoted from the MASM reference:
Returns a word defining the mode and scope of expression. The low byte is identical to the byte returned by .TYPE. The high byte contains additional information.
The values are as follows, taken from the MASM Basic
source code referenced here at the MASM forum:
; OPATTR guide
; Bit Set If...
; 0 References a code label
; 1 Is a memory expression or has a relocatable data label
; 2 Is an immediate expression
; 3 Uses direct memory addressing, i.e. is an absolute memory reference
; 4 Is a register expression
; 5 References no undefined symbols and is without error
; 6 References a stack location (usually a LOCAL variable or parameter)
; 7 References an external label
; 8-10 Language type (000=no type)
; 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
There are mentioned some examples of usage:
atMemory = 34 ; 00100010 ; [edx+20], [ebx+20], [eax+edx+20], JWasm: [eax+4*eax+20], [eax+20]
atImmediate = 36 ; 00100100
atLabel = 37 ; 10100101
atOffset = 38 ; 10100110 ; offset CrLf$ (immediate and mem expression)
atGlobal = 42 ; 10101010 ; CrLf$, Masm: [eax+4*eax+20], [eax+20]
atRegLabel = 43 ; 10101011 ; Masm: [eax+start] (Jwasm yields 37)
atRegister = 48 ; 00110000 ; also xmm
atXmm = 77 ; xxxxxxxx ; reg starting with x
atLocal = 98 ; 01100010 ; [esp+20], [ebp+20]
An example for your MACRO code would be
mWriteInt MACRO integer:REQ
IF(OPATTR(integer) EQ 24h AND SIZEOF(integer) EQ 4) ; immediate and no undefined symbols
; for a DWORD
mov eax, dword ptr integer
call WriteInt
ELSEIF (OPATTR(integer) EQ 24h AND SIZEOF(integer) EQ 2) ; immediate and no undefined symbols
; for a WORD
movsx eax, word ptr integer
call WriteInt
ELSEIF (OPATTR(integer) EQ 24h AND SIZEOF(integer) EQ 1) ; immediate and no undefined symbols
; for a BYTE
movsx eax, byte ptr integer
call WriteInt
ENDIF
mov edx, OFFSET endl
call WriteString
ENDM
If this MACRO code is not exactly what you expect, you can adjust the OPATTR
value by combining the bit values.
One thing to add to describe the difference in MASM between the two variants of IFs:
IF --- is compile time comparison
.IF --- is runtime comparison
Upvotes: 4