Io-stream
Io-stream

Reputation: 109

How do you compare variable types in assembly?

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

Answers (1)

zx485
zx485

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

Related Questions