Булевые конструкции

Последнее обновление: 02.07.2023

Многие языки программирования оценивают условия как значения логических типов (обычно нызваются bool или boolean). В ассемблере мы также можем представить условия в виде своего рода логических значений, а по сути чисел, которые равны или 1 (условие верно) или 0 (условие не верно). Для примера возьмем условие

if(((a == b) && (c != d)) || (e == f))

С помощью инструкции setXX в зависимости от результата проверки мы можем установить условные логические значения

.data
    a dword 22
    b dword 22
    c dword 23
    d dword 24
    e dword 25
    f dword 26
.code
main proc
begin_if:
    mov eax, a
    cmp eax, b      ; (a==b)
    sete bl         ; результат сравнения (a==b) в регистре BL
    
    mov eax, c
    cmp eax, d     ; (c!=d)
    setne bh       ; результат сравнения (c!=d) в регистре BH

    and bl, bh     ; Помещаем в регистр BL результат (a==b) && (c!=d)

    mov eax, e
    cmp eax, f     ; (e==f)
    sete bh        ; результат сравнения (e==f) в регистре BH
 
    or bl, bh       ; Помещаем в регистр BL результат (((a == b) && (c != d)) || (e == f))

    je end_if     ; если все условие не верно, переходим к end_if

    mov eax, 1     ; если условие верно
end_if:
    ret
main endp
end

Здесь вначеле проверяем первое условие из подусловия AND - (a==b):

mov eax, a
cmp eax, b      ; (a==b)
sete bl         ; результат сравнения (a==b) в регистре BL

Если числа a и b равны, то в регистр BL помещается 1.

Затем проверяем второе условие из подусловия AND - (c!=d):

mov eax, c
cmp eax, d     ; (c!=d)
setne bh       ; результат сравнения (c!=d) в регистре BH

Если числа c и d не равны, то в регистр BH помещается 1.

Далее с помощью инструкции and можно оценить весь результат подусловия AND:

and bl, bh     ; Помещаем в регистр BL результат (a==b) && (c!=d)

Таким образом, если оба условия истинны, то в регистре BL будет 1, иначе будет 0.

Затем проверяем третье условие - подусловие OR - (e==f):

mov eax, e
cmp eax, f     ; (e==f)
sete bh        ; результат сравнения (e==f) в регистре BH

И с помощью инструкции or проверяем результат всего условия (((a == b) && (c != d)) || (e == f))

or bl, bh       ; Помещаем в регистр BL результат (((a == b) && (c != d)) || (e == f))
je end_if     ; если все условие не верно, переходим к end_if

Если оба регистра равны 0 (оба подусловия неверны), то устанавливается флаг нуля. Соответственно мы можем проверить этот флаг и, если он установлен, перейти к метке завершения конструкции if.

Стоит отметить, что примере выше вычисления производились в полной форме, все три условия вычислялись. Однако, если мы возьмем подусловие (a == b) && (c != d), то тут нет смысла вычислять второе условие, если первое условие не верно. Аналогично если верно улсовие ((a == b) && (c != d)), то подусловие (e == f) нет смысла вычислять. Поэтому в определенных ситуациях может быть предпочтительно вычисление по укороченной схеме или то что называется "short-circuit", как было продемонстрировано в предыдущем примере.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850