【问题标题】:How do you compare variable types in assembly?你如何比较汇编中的变量类型?
【发布时间】:2016-08-26 16:56:39
【问题描述】:

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

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

【问题讨论】:

  • 您通常不会使用 CPU 指令进行比较,而是使用像 IF 这样的指令。
  • MASM 中的 IF 指令不像 C 中的 if 语句那样工作。msdn.microsoft.com/en-us/library/4bd8b239.aspx
  • 好的,我应该在发布之前用谷歌搜索一下。我再次尝试,没有错误并且它运行,但它似乎没有工作。无论我通过什么类型,代码似乎永远不会执行
  • 想想您希望宏生成的指令:cmp immediate, immediate。没有这样的编码,因为那将是一个无用的指令。无论如何,既然你已经摆脱了那个脑残,你应该将你的答案作为答案发布,而不是作为对问题的编辑。
  • @PeterCordes 感谢您的输入,但我不太明白您所说的立即,立即是什么意思?我还发布了一个编辑,因为代码仍然没有按照预期的方式执行,但是如果我应该将它作为答案发布,我深表歉意

标签: assembly macros masm


【解决方案1】:

在 MASM 中有 OPATTR 运算符。引用自the MASM reference

返回一个定义表达方式和范围的词。低字节与 .TYPE 返回的字节相同。高字节包含附加信息。

取值如下,取自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]

你的宏代码的一个例子是

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

【讨论】:

  • 哇,这是一个非常彻底的答案。你所说的对我来说很有意义,但是当我添加你的代码时,我得到了相同的结果(只有 endl BYTE 打印)。我通过它的方式可能有问题吗?我正在调用:mWriteInt [edi],当代码中没有 if 语句时效果很好
  • 这可能是错误的根源:您正在调用mWriteInt [edi][edi] 具有未指定的大小 - 它是 dword ptr [edi]word ptr [edi]byte ptr [edi] 的快捷方式。你可能已经习惯了这个快捷方式,因为mov al, [edi] 推断 BYTE 大小,mov eax, [edi] 推断 DWORD 大小,分别。但是,如果您想在 MACRO 中按大小进行区分,您必须指定大小,否则所有可能性都会匹配,因此 OPATTR 无法做出任何决定。
  • 非常感谢,你太棒了!!这完全解决了我的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-20
  • 2020-10-16
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
相关资源
最近更新 更多