использование x86 .ЕСЛИ , ИНАЧЕ , и .ИНАЧЕ, если сравнить два числа

# #if-statement #assembly #x86 #masm

Вопрос:

Мне дают два значения DWORD, и я буду сравнивать их оба , используя .IF , .ELSE , .ELSEIF чтобы увидеть, какое число больше или если они оба равны. Например, на экран выводятся два запроса: «Введите номер 1» и «Введите номер 2». Числа 1 и 2 хранятся в отдельных регистрах с использованием eax для num1 и ecx для num2. ЕСЛИ eax и ecx равны, вызывается приглашение «Равно». Если это не так, то вот .ELSEIF в чем дело. eax сравнивается с ecx и наоборот.

Единственная проблема заключается в том, что число два всегда больше первого значения, если они не равны.

 include asmlib.inc
.data

Prompt  BYTE    " Enter a number ", 0     ;Type number 1
Prompt2 BYTE    " Enter another number ", 0 ;Type number 2
Large   BYTE    " Is larger ", 0 ;Larger number output
Equal   BYTE    " Is equal", 0  ;Numbers are equal output
num1    DWORD ? ;Number 1 is num1
num2    DWORD ? ;Number 2 is num2

.code
main PROC

mov edx, OFFSET Prompt ;Enter first number
call writeLine
call readInt
mov num1, eax
endl

mov edx, OFFSET Prompt2 ;Enter second num
call writeLine
call readInt
mov num2, ecx
endl

.IF  eax == ecx
mov edx, OFFSET Equal   ;display Equal output
call writeString    ;display line
.ENDIF 

.IF ecx > eax amp;amp; eax < ecx
mov ecx, num2
call    writeInt
mov edx, OFFSET Large
call    writeString

.ELSEIF ecx < eax amp;amp; eax > ecx
mov eax, num1
call    writeInt
mov edx, OFFSET Large
call    writeString
.ENDIF

exit
main ENDP
end main
 

Комментарии:

1. Во-первых, вам нужно сравнивать только eax < ecx , а не в обоих направлениях (как в eax < ecx amp;amp; ecx > eax ). Затем вы должны скопировать значение большего значения в тот же регистр. Я не знаю, в каком регистре writeInt ожидает аргумент, но он должен быть одинаковым в обоих случаях. Кроме того, правильное значение уже находится либо в правильном регистре, либо в другом регистре, что означает, что нет необходимости загружать данные из памяти. Таким образом mov eax, ecx , или mov ecx, eax только в одной из ветвей, или даже swap ecx, eax . В любом случае, вы можете сохранить код с помощью .IF cond; swap; .ENDIF

Ответ №1:

 mov edx, OFFSET Prompt2 ;Enter second num
call writeLine
call readInt
mov num2, ecx
 

Все .IF , .ELSEIF .ELSE .ENDIF что может сделать,,, или, становится недействительным из-за ошибки при получении входных данных программы.
readInt возвращает целое число в EAX регистре, и поэтому ваша mov num2, ecx инструкция должна гласить mov num2, eax

Единственная проблема заключается в том, что число два всегда больше первого значения, если они не равны.

Если ecx > eax вы отображаете «Больше», и если ecx < eax вы также отображаете «больше». А чего ты ожидал?

  • До получения первых .IF eax == ecx инструкций вы должны загрузить EAX данные из num1 и ECX из num2.
  • Если числа окажутся равными, вы не захотите их использовать .ENDIF , потому что это заставит вас провалиться и дополнительно (и без необходимости) выполнить сравнение для «больше, чем».
 mov eax, num1
mov ecx, num2
.IF eax == ecx
    mov     edx, OFFSET Equal
    call    writeString
.ELSEIF eax > ecx
    call    writeInt
    mov     edx, OFFSET Large
    call    writeString
    mov     eax, ecx        ; ecx = num2
    call    writeInt
.ENDIF