Многие языки программирования оценивают условия как значения логических типов (обычно нызваются 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", как было продемонстрировано в предыдущем примере.