你如何比较汇编中的变量类型?
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
这可能是一个有点愚蠢的语法问题,但是有没有一种方法可以根据变量类型进行条件跳转?我正在尝试编写一个可以将字节、字或双字作为参数并将其写入屏幕的宏(对于 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