Команды расширения знака.

CBW преобразует байт в регистре AL в слово в регистре АХ путем расширения знакового бита AL во все биты регистра AH. Команда CWD преобразует слово в регистре АХ в двойное слово , расположенное в паре регистров DX, AX путем расширения знакового бита регистра AX во все биты регистра DX.

Новые команды расширения знака

Начиная с микропроцессора 80386, существуют еще две команды расширения знака CWDE и CDQ. CWDE преобразует слово в расширенное двойное слово путем расширения знакового разряда АХ во все старшие разряды регистра ЕАХ. CDQ преобразует двойное слово в регистре ЕАХ в учетверенное слово в паре регистров EDX, EAX путем расширения знакового разряда ЕАХ во все разряды EDX.

2.5.2.5.Десятичная арифметика.

До сих пор мы рассматривали арифметические операции под двоичными числами, так как компьютеры работают только с двоичными числами, но для людей более привычны десятичные числа. Поэтому возникает проблема преобразования десятичных чисел в двоичные. Можно десятичное число представить в двоичной системе полностью, кодом, например 37 - 00100101, а можно закодировать отдельно каждую цифру 3 и 7 и получить код 0011 0111. Такое двоичное изображение десятичных чисел называется двоично-десятичным кодированием (BCD - кодом). Для выполнения арифметических операций над числами в данном формате потребовалось бы ввести соответствующие команды сложения, вычитания, умножения и деления. Возможен и второй вариант: применить к таким числам команды двоичной арифметики, заранее зная о неправильном результате, а затем выполнить команду коррекции, которая сформирует правильный результат в BCD формате. Именно такой вариант был выбран в процессорах семейства 8086.

Рассмотрим сложение чисел 23 и 14 в BCD формате с помощью двоичного сложения:

=  
=  
= Результат правильный, коррекция не нужна

Сложим 29 и 14:

=  
=  
= 3? Ответ неверен, так как код 1101 не соответствует десятичной цифре, требуется коррекция.

Коррекция заключается в том, чтобы добавить 6 к сумме в тех разрядах, где получена запрещённая комбинация, компенсируя этим, 6 запрещённых комбинаций для десятичных чисел (4 разряда - 16 комбинаций, 10 цифр пра­вильных, 6 - лишних).

= 3?  
        =  
= Результат правильный

Более сложная ситуация возникает, когда сумма “проскакивает” запрещённый диапазон и становится допусти­мой цифрой.

Сложим 29 и 18:

=  
=  
= Результат неверный, так как младшая цифра проскочила запрещенный диапазон.

При коррекции требуется добавить 6 и получить правильный результат 47. Однако необходимость такой коррекции невозможно определить по самому результату. Признаком “проскока” цифрой запрещённого диапазона служит перенос из соответствующего бита (разряда). В приведённом примере им будет перенос из младшего (десятичного) разряда в старший. Флаг CF показывает, что при сложении возник перенос из старшего бита (разряда), флаг вспомогательного переноса AF предназначен только для регистрации переноса из младшего 10-го разряда, зная который можно осуществить коррекцию. После сложения в нашем примере CF = 0 и AF = 1 (если CF = 1, то при следующем сложении надо учитывать его и сумму).

Десятичную коррекцию сложения осуществляет команда DAA, в которой предполагается, что сумма находится в регистре AL. С учётом содержимого AL и состояний флагов AF и CF команда DAA определяет необходимость коррекции и реализует её для AL.

Аналогично команда DAS корректирует результат после операции вычитания.

Для умножения чисел в формате BCD произвести коррекцию невозможно, так как в результате “замешаны” перекрёстные члены произведения. Аналогично и для команды деления. Следовательно, для умножения и деления необходимо перейти к другому представлению десятичных чисел. BCD формат называется упакованным, а в неупакованном формате байт содержит всего одну десятичную цифру. Она находится в 4-х младших битах, а старшие биты не влияют на значение цифры. Примером такого формата служит код ASCII, в котором символы представлены 8 битами. ASCII-коды десятичных цифр представлены в таблице 2.9.

Таблица 2.9. ASCII-коды десятичных цифр.

Цифра Код

 

Четыре бита 0011 не влияют на значение цифры, однако, должны быть обнулены до выполнения арифметических операций.

Результаты двоичного сложения и вычитания ASCII-чисел можно скорректировать аналогично коррекции в BCD формате, причём корректируется только младшая цифра. В системе команд микропроцессора существуют специальные команды коррекции:

AAA - ASCII коррекция сложения.

AAS - ASCII коррекция вычитания.

AAM - ASCII коррекция умножения.

AAD - ASCII коррекция деления.

Пример: умножим 9 * 4, 9 - находится в регистре BL, а 4 - в регистре AL.

BL: 00001001 = 9 ½ MUL BL - даёт в AX 16-битный результат, равный 36

AL: 00000100 = 4 ½36 = 0000 0000 0010 0100

Команда коррекции AAM должна “разложить” результат на 3 (00000011) в регистре AH и 6 в регистре AL. Для этого нужно просто раз делить содержимое AL на 10 и поместить частное в AH, а остаток в AL.

Поэтому команда AAM имеет длину 2 байта, так как второй байт - это представление 10. В рассмотренном примере старшие биты были нулевыми, иначе результат нельзя скорректировать. Поэтому перед умножением неупакованных десятичных чисел следует сбросить четыре старших бита в 0.

Рассмотрим деление неупакованных десятичных чисел, например 42/6. 42 находится в AL (0000 0100 в AH и 0000010 в AL), а 6 (00000110) в BL. Неупакованное представление одноразрядного числа 6 является его двоичным представлением, следовательно, нужно преобразовать 42 в двоичное число. Для этого AH следует умножить на 10 и сложить с содержимым регистра AL. Тогда при делении в AL получится число 7, двоичное представление которого совпадает с неупакованным представлением. Команда коррекции деления имеет свои особенности:

AAD - двухбайтовая команда (второй байт - 10).

Коррекция AAD предшествует делению, а в сложении, вычитании и умножении производится после опера­ции.

Делимое и делитель (множимое и множитель) должны иметь 0 в старших 4-х битах.

2.5.3.Логические команды.

Перечень логических команд и их описание приведено в таблице 2.10.

 

 

Таблица 2.10. Перечень логических команд.

  Мнемоника Описание
Булевы команды AND (и) приемник и источник à приемник
  TEST приемник и источник à
  OR (или) приемник или источник à приемник
  XOR (исключающее или) приемник Å источник à приемник
  NOT (инверсия) не приемник à приемник
Команды SHL (логический сдвиг влево) CF ß приемник ß 0
сдвигов SHR (логический сдвиг вправо) 0 à приемник à CF
  SAL (арифметический сдвиг влево) CF ß приемник ß 0
  SAR (арифметический сдвиг вправо) знак à приемник à CF
Команды циклических ROL (циклический сдвиг влево)  
сдвигов ROR (циклический сдвиг вправо)  
  RCL (циклический сдвиг влево через перенос)  
  RCR (циклический сдвиг вправо через перенос)  
Начиная с м/п 80386 дополнительные команды:
Команды двойного сдвига SHLD (сдвиг с двойной точностью влево)  
  SHRD (сдвиг с двойной точностью вправо)  
Команды работы с двоичными цепочками BT (поиск бита и запись его в CF)  
  BTC (поиск и инвертирование бита в цепочке)  
  BTS (поиск и установка бита в)  
  BTR (поиск и сброс бита )  
  BSF (сканирование цепочки битов вперед)  
  BSR (сканирование цепочки битов назад)  

2.5.3.1.Булевы команды.

К булевым командам относятся команды AND, OR, XOR, NOT, TEST.

Команды AND, OR, XOR выполняют логическую функцию над соответствующими битами источника и приёмника, помещая результат в приёмник. Все команды двухоперандные , разрешённые форматы операндов такие же, как у команд ADD, ADC, SUB, SBB.

Команда NOT - однооперандная, она выполняет инверсию каждого бита операнда и помещает результат в то же место. Формат команды такой же, как у команд DEC, NEG, INC.

Команда AND удобна для обнуления указанных разрядов числа: один операнд определяет разряды, а второй число. Например: обнуление старших 4-х битов в байте с именем MEMB (AND MEMB, 00001111B).

Команда OR используется для установки указанных битов, а команда XOR используется для инвертирования указанных разрядов в числе. XOR позволяет также сбросить содержимое регистра в нуль (регистр должен быть и источником и приёмником).

Команда TEST - двухоперандная, формат совпадает с командами ADD, ADC, SUB, SBB. Объединяет возможности команд AND и CMP, Как AND она выполняет объединение по “и” соответствующих бит операндов, как CMP она сохраняет только состояния флагов, а не результат. Удобна для проверки того, есть ли в указанных разрядах числа хотя бы одна 1. Один операнд определяет разряды, второй - число. Если результат нера­вен 0, то, по крайней мере, один разряд равен 1. Все логические команды кроме NOT изменяют флаги SF, ZF, PF. Флаг AF - не определён, а CF = 0 и OF = 0, DF, IF, TF - не изменяются.

2.5.3.2.Команды сдвигов.

Команды сдвигов являются эффективным средством увеличения или уменьшения числа в 2 раза (меньше памяти и быстрее, чем в командах умножения и деления). Для умножения числа на 2, надо сдвинуть все биты на 1 разряд влево, а в освобождённый правый бит поместить 0. Если выдвинутый слева бит передать во флаг CF, то можно зафиксировать выход за диапазон, проверив условие CF = 1. Аналогично уменьшение беззнакового числа вдвое осуществляется сдвигом всех бит на один разряд вправо, а в освобождающийся бит помещается 0. Вдвигаемый справа бит передаётся во флаг CF, если CF = 1, то число нечётное. С беззнаковыми числами работает команда SHL и SHR, а команды SAL и SAR предназначены для знаковых чисел. SAR сохраняет знаковый бит неизменным, команда SHR помещает в знаковый бит 0 (но заносит 1 во флаг OF, если знак имеется). Отметим, что сдвиг вправо нечётного числа всегда даёт результат, который меньше половины числа, например:

-5 (1111 1011) SAR -3 (1111 1101)

-3 < -2.5

При делении -5 на 2 командой DIV результат будет = -2. Различий между удвоением знакового и беззнакового чисел нет.


Рисунок 2.3.

Графическое представление работы команд сдвигов