-
Условный оператор со сложным условием
Если условие сложное, то обычно выполняют проверку составляющих его простых условий, осуществляя после каждой проверки необходимые переходы.
ПРИМЕР
Если бит номер 1 байтовой переменной R равен 0 и бит номер 5 равен 1, перейти на метку DA, иначе на метку NET
Из формулировки задачи следует, что переход на метку DA осуществляется, когда выполняются и первое, и второе условие одновременно, другими словами, если хотя бы одно условие не выполняется, должен быть переход на метку NET.
test R, 10b ; проверка бита номер 1
jnz net ; если бит ≠ 0, переход на net
test R, 100000b ; проверка бита номер 5
jz net ; если бит = 0 ( т.е. ≠1), переход на net
; первый бит = 0 и пятый ≠ 0 ( =1)
da: ……
jmp fin
net: …….
fin: ……
ПРИМЕР
Если бит номер 1 байтовой переменной R равен 0 или бит номер 5 равен 1, перейти на метку DA, иначе на метку net.
Переход на метку DA осуществляется, когда выполняется хотя бы одно условие.
test R, 10b ; проверка бита номер 1
jz da ; если бит = 0, переход на da
; первый бит ≠ 0, необходимо проверить пятый
test R, 100000b ; проверка бита номер 5
jnz da ; если бит . ≠ 0 ( т.е. =1), переход на da
; ни один заданный бит не удовлетворяет заданному условию
; переход на net (следующая команда)
net: …….
jmp fin
da: ……
fin: ……
-
Команды сдвига
3.4.1 Команды сдвига перемещают (сдвигают) биты в поле операнда op (приемника) влево (L) или вправо (R) на число разрядов, указанных в счетчике:
<мнемокод> op, <счетчик>
Операнд op может быть регистром или памятью, а <счетчик> – либо непосредственным операндом, либо регистром CL.
3.4.2 Команды по принципу действия различаются на линейные и циклические.
Линейные – это логический (беззнаковые числа) и арифметический (знаковые числа) сдвиги, выполняемые по алгоритму: выдвигаемый бит попадает в СF, при этом значение предыдущего сдвинутого бита теряется, а бит, вводимый с другого конца, равен 0.
Логический сдвиг влево (shift left): SHL op, <счетчик>
Логический сдвиг вправо (shift right): SHR op, <счетчик>
Условно действия этих команд можно изобразить так, как показано на рисунке 3.1 (слева - для SHL, справа - для SHR).
CF op op CF
0 0
Рисунок 3.1 – Схема действия команд логического сдвига
Замечание: команды сдвигают в памяти переменные, большие байта, так, как если бы они было записаны в "неперевернутом" виде.
ПРИМЕР
Х DW 1FFh ; 00000001 11111111b (X: 11111111b, X+1: 00000001b)
SHL X, 1 ; 00000011 11111110b (X: 11111110b, X+1: 00000011b)
Арифметический сдвиг влево (shift arithmetic left): SAL op, <счетчик>
Арифметический сдвиг вправо (shift arithmetic rigth ): SAR op, <счетчик>
Команда SAL аналогична SHL.
SAR сохраняет знак, восстанавливая его после сдвига каждого очередного бита (рисунок 3.2).
оp CF
Рисунок 3.2 – Схема действия команды SAR
3.4.3 Линейные команды применяются для быстрого умножения и деления операнда оp на число, представляющее собой степень двойки 2k:
-
умножение беззнаковых и знаковых чисел (SHL или SAL) – сдвиг на k позиций влево обеспечивает умножение операнда на 2k ;
-
получение неполного частного при делении на 2k беззнаковых (SHR) и знаковых (SAR) чисел - сдвиг операнда на k позиций вправо;
-
получение остатка от деления беззнаковых чисел на 2k – выделить в делимом (операнде) k правых битов.
3.4.4 Особенность циклических сдвигов: "уходящий" бит не теряется, а возвращается в операнд с другого конца и одновременно заносится во флаг CF.
Циклический сдвиг влево (rotate left): ROL op, <счетчик>
Циклический сдвиг вправо (rotate right): ROR op, <счетчик>
Схема действия этих команд изображена на рисунке 4.3 (слева - для ROL , справа - для ROR ).
CF op op CF
Рисунок 3.3 – Схема действия команд логического сдвига
ПРИМЕР
MOV CL, 11000011b
ROL CL, 1 ; CF=1, CL=10000111b
MOV BH, 11100010b
ROR BH, 1 ; BH=01110001b, CF=0
Команды часто используются для перестановки частей содержимого ячейки или регистра.
ПРИМЕР
Поменять местами правую и левую половины регистра AL.
Задание можно выполнить циклическим сдвигом байта на 4 разряда влево (или вправо):
MOV AL, 17h ; AL=00010111b – начальное значение регистра
MOV CL, 4
ROL AL, CL ; AL=01110001b=71h
Циклический сдвиг влево через перенос (rotate lefh through carry):
RCL op, <счетчик>
Циклический сдвиг вправо через перенос (rotate rigth through carry):
RCR op, <счетчик>
По команде RCL все биты первого операнда сдвигаются на одну позицию влево, причем самый левый бит попадает во флаг CF, а прежнее значение этого флага заносится в самый правый разряд операнда (на рисунке 3.4 слева); в команде RCR все аналогично, только осуществляется сдвиг вправо (на рисунке 3.4 справа):
CF op op CF
Рисунок 3.4 – Схема действия команд циклического сдвига
ПРИМЕР
Пусть начальное значение CF=0, а регистр BL содержит 11110000b.
RCL BL, 1 ; CF=1, BL=11100000b
RCL BL, 1 ; CF=1, BL=11000001b
Рассматриваемые команды обычно используются при переносе битов из одного регистра (или переменной) в другой.
ПРИМЕР
Сдвинуть на 3 разряда влево значения регистров AL и DH, приписав справа к AL три левых бита регистра DH:
MOV СХ, 3 ; счетчик количества сдвигаемых бит
L: SHL DH, 1 ; в СF бит номер 7 (левый) из DH
RCL AL, 1 ; бит из СF в бит номер 0 (правый) AL
DEC CX ; CX := CX – 1
CMP CX, 0 ; CX = 0? (все биты перемещены?)
JNE L ; если не все на L