Assembly 如何比较程序集中的变量类型?

Assembly 如何比较程序集中的变量类型?,assembly,macros,masm,Assembly,Macros,Masm,这可能是一个愚蠢的语法问题,但有没有一种方法可以基于变量类型进行条件跳转?我正在尝试编写一个宏(针对一个类),它可以将一个字节、一个单词或两个单词作为参数并将其写入屏幕 mWriteInt MACRO integer:REQ ;cmp integer, DWORD ;je dwordOp movsx eax, word ptr integer call WriteInt mov edx, OFFSET endl call WriteString ; f

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

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
运算符。引自:

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

值如下所示,取自参考的
MASM Basic
源代码:

这里提到了一些用法示例:

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
如果此宏代码与您期望的不完全一样,您可以通过组合位值来调整
OPATTR

需要补充一件事来描述IFs两种变体之间MASM的差异:

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

你通常不会使用CPU指令来进行比较,你会使用像IF这样的指令。MASM中的IF指令不像C中的IF语句那样工作。好的,在发布lol之前我应该在谷歌上搜索一下。我再试了一次,没有错误,它运行了,但似乎不起作用。无论我传递的是哪种类型,代码似乎都不会执行您希望宏生成的指令:
cmp immediate,immediate
。没有这样的编码,因为那将是一条无用的指令。不管怎样,既然你已经通过了大脑放屁,你应该把你的答案作为答案,而不是作为问题的编辑来发布。@PeterCordes谢谢你的输入,但我不太明白你说的立即,立即是什么意思?我还发布了一个编辑,因为代码仍然没有按预期的方式执行,但是如果我应该发布它作为一个答案,我道歉哇,这是一个非常彻底的答案。你所说的对我来说很有意义,但是当我完全添加你的代码时,我得到了相同的结果(只打印endl字节)。我通过它的方式会有问题吗?我正在调用:mWriteInt[edi],当代码中没有if语句时,它工作得非常好。这可能是错误的根源:您正在调用
mWriteInt[edi]
[edi]
的大小未指定-它是
dword ptr[edi]
word ptr[edi]
字节ptr[edi]
的快捷方式。您可能已经习惯了这个快捷方式,因为
mov al,[edi]
分别推断字节大小和
mov eax,[edi]
分别推断DWORD大小。但是如果你想在宏中通过大小来区分,你必须指定大小,否则所有的可能性都会匹配,因此OPATTR无法做出决定。非常感谢你,你太棒了!!这完全解决了我的问题
IF   --- is compile time comparison  
.IF  --- is runtime comparison