- •3.11.1 Команды пересылки данных
- •Команды пересылки общего назначения
- •Xchg приемник, источник
- •Команды загрузки адресных значений
- •Команды обращения к стеку
- •Команды пересылки флагов
- •Команды ввода/вывода
- •In аккумулятор, порт
- •In аккумулятор, dx.
- •3.11.2. Арифметические команды
- •Типы арифметических данных
- •Команды инкрементирования и декрементирования
- •Inc приемник
- •Команды сложения и вычитания
- •Команды расширения знака
- •Команды умножения и деления
- •Imul источник.
- •Команды десятичной коррекции
- •Сложение в bdc-формате
- •Вычитание в bcd-формате
- •Сложение в ascii-формате
- •Вычитание в ascii-формате
- •Умножение в ascii-формате
- •Деление в ascii-формате
- •3.11.3 Логические команды
- •Команды логических операций
- •Команды сравнения
- •Команды сдвигов
- •Команды логических сдвигов
- •Команды арифметических сдвигов
- •Команды циклических сдвигов
- •3.11.4. Команды передачи управления
- •Команды безусловных переходов
- •Команды условных переходов
- •Команды перехода по состоянию арифметических флагов
- •Команды перехода по соотношению между числами
- •Команды перехода по состоянию регистра cx
- •Команды управления циклами
- •Команды для организации подпрограмм
- •Команды прерываний
- •3.11.5. Команды обработки строк
- •Строковые примитивы
Команды логических сдвигов
К этой подгруппе относятся команды SHR и SHL, предназначенные для сдвига нечисловых значений (например, масок), а также для сдвига чисел без знака.
Команда SHR сдвигает операндприемник вправо, а команда SHLвлево в соответствии со схемами, приведенными на рис. 3.5,а. Эти команды помещают в освобождающиеся после сдвига биты нулевые значения.
Пример 3.85:
SHR AX, 1 ;Сдвиг регистра на 1 бит вправо
SHL BYTE PTR [BX],CL;Сдвиг байта в памяти на (CL)
;разрядов влево
Рис. 3.5. Операции сдвига:
а) логические сдвиги; б) арифметические сдвиги; в) циклические сдвиги
Команды логического сдвига также используются для сдвига операндов при преобразовании форматов десятичных чисел.
Пример 3.86:
Преобразовать десятичные ASCII-числа из регистров AL,BL в BCD-формат.
MOV CL, 4 ; Загрузка счетчика сдвигов
SHL AL, CL ; Сдвиг старшей цифры
OR AL, BL ; Формирование BCD-числа
Поскольку сдвиг операнда на один бит влево эквивалентен умножению его на 2, а сдвиг на один бит вправо его делению на 2, то команды сдвига можно использовать для быстрого умножения и деления чисел. При этом умножение возможно на любое число и сводится к некоторой комбинации операций сдвигов влево и сложения, а деление возможно лишь на степень числа 2 (2,4,8,16, . . .) и сводится к выполнению соответствующего количества сдвигов вправо.
Пример 3.87:
Умножить число без знака из регистра AX на 53.
Для определения требуемой комбинации операций сдвига и сложения в общем случае необходимо константумножитель представить в виде двоичной схемы Горнера. Для числа 53 это представление имеет вид:
53=00110101b=((((((0·2+0)2+1)2+1)2+0)2+1)2+0)2+1
Реализация этой схемы начинается с внутренних скобок.
MOV DX, AX ; Копирование для последующих
; сложений
SHL AX, 1 ; Умножение на 2
ADD AX, DX ; Умножение на 3
SHL AX, 1 ; Умножение на 6
SHL AX, 1 ; Умножение на 12
ADD AX, DX ; Умножение на 13
SHL AX, 1 ; Умножение на 26
SHL AX, 1 ; Умножение на 52
ADD AX, DX ; Умножение на 53
Хотя в этой последовательности 8 команд, но выполняется она в 7 раз быстрее, чем одна команда MUL!
Команды логического сдвига правильно формируют флаги SF, ZF и PF. Флаг переноса CF формируется в соответствии со схемой сдвига (см. рис. 3.5,а). При сдвиге беззнаковых чисел влево флаг CF=1 показывает, что результат вышел за допустимый диапазон, а при сдвиге вправо флаг CF содержит остаток от деления на 2.
Флаг переполнения OF имеет достоверное значение лишь при однократном сдвиге. При этом OF=0, если два старших бита операнда равны, и OF=1 в противном случае.
Команды арифметических сдвигов
К этой подгруппе относятся команды SAL и SAR, предназначенные для сдвига знаковых чисел. Арифметический сдвиг отличается от логического сдвига тем, что знаковый разряд не сдвигается и сохраняет свое значение.
Команда SAL сдвигает операнд-приемник влево, а команда SAR вправо в соответствии со схемами, приведенными на рис. 3.5,б. При этом при сдвиге вправо знаковый (старший) бит операнда дублируется в соседнем правом разряде, сохраняя свое значение, т.е. знак числа. Арифметический сдвиг влево совпадает с логическим сдвигом влево. Это обусловлено тем, что в дополнительном коде все старшие разряды числа, не хранящие его модуль, хранят его знак. Поэтому команды SAL и SHL идентичны, и обе мнемоники сохранены лишь для точного отражения содержательного смысла выполняемой операции.
Команды SAL и SAR используются для быстрого умножения и деления знаковых чисел на константу аналогично командам SHL и SHR (см. пример 3.87). Однако, необходимо помнить, что результат деления отрицательного числа с помощью команды SAR не совпадает с результатом его деления с помощью команды IDIV. Например, результат операции (7)/2 (7=11111001b), полученный командой SAR, равен (4), а командой IDIV (3). Это объясняется тем, что команда IDIV усекает и положительное и отрицательное частное к нулю путем отбрасывания дробной части, а команда SAR усекает положительные числа к нулю, а отрицательные к минус бесконечности.
Команды SAL и SAR формируют флаги идентично командам SHL и SHR. Однако, правилу формирования флага OF можно дать другую трактовку. Флаг переполнения OF=1, если в результате сдвига изменился знак числа (при умножении на 2 результат вышел из диапазона, т.е. возникло переполнение). При сдвиге вправо это условие никогда не выполняется, и всегда OF=0.
Пример 3.88:
MOV DL, 25 ;Сдвиг числа (25)=11100111b влево:
SAL DL, 1 ;(DL)= 50=11001110b, OF=0, CF=1,
;SF=1, ZF=0, PF=0
MOV DL, 25 ;Сдвиг числа (25)=11100111b вправо на 2 бита: MOV CL, 2 ;(DL)= 7=11111001b, OF=?, CF=1, SF=1,
SAR DL, CL ;ZF=0, PF=1