2016-05-02 4 views
2

Это может быть немного глупый вопрос синтаксиса, но есть ли способ сделать условные переходы на основе типа переменной? Я пытаюсь написать макрос (для класса), который может принимать байт, слово или двойное слово в качестве аргумента и записывать его на экран.Как вы сравниваете типы переменных в сборке?

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 

, и я не знаю, куда идти отсюда. Я посмотрел в каждой ссылки я могу думать, но это, кажется, не быть обычным делом

Edit:

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 
+2

Вы обычно не использовать инструкцию процессора сделать сравнение, нужно использовать директиву как IF. –

+0

Директивы IF в MASM не работают, как в операторах на C. https://msdn.microsoft.com/en-us/library/4bd8b239.aspx –

+0

Хорошо, что-то, что я должен был использовать для googled перед публикацией LOL. Я попробовал еще раз, никаких ошибок и не работает, но, похоже, он не работает. независимо от того, какой тип я передаю, код никогда не кажется выполненным –

ответ

4

В MASM Eсть 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, объединив значения бит.

Одна вещь, чтобы добавить, чтобы описать разницу в MASM между двумя вариантами МСФ:

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

Вау, это такой невероятно тщательный ответ.То, что вы говорите, имеет смысл для меня, но когда я добавляю даже ваш код точно, я получаю тот же результат (только отпечатки endl BYTE). Может быть что-то не так с тем, как я это передаю? Я вызываю: mWriteInt [edi], который отлично работает, когда в коде нет операторов if. –

+2

Это может быть корень ошибки: вы вызываете 'mWriteInt [edi]'. '[edi]' имеет неуказанный размер - это ярлык для 'dword ptr [edi]', 'word ptr [edi]' или 'byte ptr [edi]'. Вероятно, вы привыкли к этому ярлыку, потому что 'mov al, [edi]' определяет размер BYTE и 'mov eax, [edi]' соответственно определяет размер DWORD. Но если вы хотите различить по размеру в MACRO, вы должны указать размер, потому что в противном случае все возможности будут соответствовать, и поэтому OPATTR не может принять никакого решения. – zx485

+0

Огромное вам спасибо, ты классный !! Это полностью решило мою проблему –

Смежные вопросы