你如何比较汇编中的变量类型?

How do you compare variable types in assembly?

这可能是一个有点愚蠢的语法问题,但是有没有一种方法可以根据变量类型进行条件跳转?我正在尝试编写一个可以将字节、字或双字作为参数并将其写入屏幕的宏(对于 class)。

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

所以基本上,执行的代码应该根据传递给宏的变量类型而有所不同。无论我如何尝试执行此操作,都会出现编译器错误。

我试过:

 cmp integer, DWORD
 cmp TYPE integer, DWORD 

而且我真的不知道从这里到哪里去。我查看了所有我能想到的参考资料,但它似乎并不常见

编辑:

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

在 MASM 中有 OPATTR 运算符。引自 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.

值如下,取自 MASM Basic 源代码引用 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

提到了一些用法示例:

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]

您的 MACRO 代码的示例是

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

如果这个MACRO代码不是您所期望的,您可以通过组合位值来调整OPATTR值。

添加一件事来描述 IF 的两种变体之间 MASM 的差异:

IF   --- is compile time comparison  
.IF  --- is runtime comparison