这可能是一个愚蠢的语法问题,但有没有办法可以根据变量类型进行条件跳转?我试图编写一个宏(对于一个类),它可以将一个字节,一个单词或双字作为参数并将其写入屏幕。
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
答案 0 :(得分:4)
在MASM中有OPATTR
运算符。引自the MASM reference:
返回定义表达式的模式和范围的单词。低字节与.TYPE返回的字节相同。高字节包含其他信息。
值如下,取自引用here at the MASM forum的MASM Basic
源代码:
; 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