ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.


http://dock-lift.ru/podstoli.html подъемный гидравлический стол.

 

Часть 3

Глава 3. Прикладное программирование.
----------------------------------------------------------------
Эта глава является обзором целочисленных команд, которые
программист может использовать при написании прикладного
программного обеспечения для процессора i486. Команды
группируются по типам связанных с ними функций. (Дополнительные
прикладные команды для работы с операндами с плавающей запятой
описаны в Части III).
Команды, не обсуждаемые в этой главе или в Части III, обычно
используются программистами операционных систем. Такие команды
системного уровня описаны в Части II.
Данное описание команд приведено для процессора i486,работающего
в защищенном режиме. Множество команд в этом режиме является 32-
разрядным расширением множества команд, используемых в
16-разрядных процессорах семейства Intel. В режиме прямой
адресации или в виртуальном режиме 86 процессор i486 имеет
архитектуру самого быстрого усовершенствованного процессора 8086
с расширенным множеством команд. Смотри главы 21,22,23,24 и 25
для более подробной информации о выполнении множества
16-разрядных команд. Все команды, описанные в данной главе,
доступны во всех режимах.
Описание множества команд в Главе 26 содержит более подробную
информацию обо всех командах, включая кодирование, выполняемые
действия, воздействие на флаги, временные характеристики и
исключения, которые могут возникать в процессе выполнения
команды.
3.1 Команды пересылки данных.
----------------------------------------------------------------
Эти команды обеспечивают удобные методы пересылки байтов, слов и
двойных слов между памятью и регистрами процессора. Они делятся
на три типа :
- Команды пересылки данных общего назначения.
- Команды работы со стеком.
- Команды преобразования типов.
3.1.1 Команды пересылки данных общего назначения.
----------------------------------------------------------------
MOV (Переслать) пересылает байт, слово или двойное слово из
операнда источника в операнд назначения. Команда MOV используется
при передаче данных между следующими элементами :
- из регистра в память;
- из памяти в регистр;
- между регистрами общего назначения;
- непосредственные данные в регистр;
- непосредственные данные в память;
Команда MOV не может пересылать данные из памяти в память или из
сегментного регистра в сегментный регистр. Пересылка из памяти в
память может быть выполнена при помощи команды пересылки строк
MOVS. Специальная форма команды MOV разработана для обеспечения
пересылки данных между регистрами AL или EAX и местом в памяти,
закодированным при помощи 32-разрядного смещения, заданного в
команде. Эта форма команды не позволяет выходить за границу
сегмента, и запрещает использование индексных регистров или
масштабирования. Кодирование данной формы команды на один байт
короче, чем кодирование команды MOV общего назначения.
Аналогичное кодирование выполняется для перемещения 8-,16- или
32-разрядов непосредственно в один из регистров общего
назначения.
XCHG (Перестановка) переставляет содержимое двух операндов. Эта
команда используется вместо трех команд MOV. Она не требует
временного размещения в памяти одного из операндов в то время,
когда другой загружается. Команда XCHG oсобенно полезна при
использовании семафоров или аналогичных структур данных в
процессе синхронизации.
Команда XCHG может менять местами два байта, два слова или два
двойных слова. Операндами для команды XCHG могут служить два
регистровых операнда или операнд-регистр и операнд,
расположенный в памяти. Когда команда XCHG использует операнд,
расположенный в памяти, она автоматически активизирует сигнал
LOCK (Смотри Главу 13 для получения более подробной информации о
блокировке шин).
3.1.2 Команды работы со стеком.
----------------------------------------------------------------
PUSH (Поместить) декрементирует указатель стека (регистр ESP),
затем копирует операнд-источник в вершину стека (см. Рисунок
3-1). Команда PUSH часто используется для размещения в стеке
параметров перед вызовом процедуры. Внутри процедуры она может
быть использована для резервирования пространства в стеке под
временные переменные. Команда PUSH работает с операндами,
размещенными в памяти, непосредственными операндами и с
регистровыми операндами (включая регистры сегмента). Специльная
форма команды PUSH возможна при размещении в стеке 32-разрядного
регистра общего назначения. Эта форма кодируется на один байт
короче, чем команда общей формы.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і                                                             і
і  ПЕРЕД РАЗМЕЩЕНИЕМ ДВОЙНОГО   ПОСЛЕ РАЗМЕЩЕНИЯ ДВОЙНОГО     і
і          СЛОВА                         СЛОВА                і
і                                                             і
і   31                   0        31                    0     і
і   ЪДДДДДДДДДДДДДДДДДДДДї        ЪДДДДДДДДДДДДДДДДДДДДДї     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   і                    іESP    ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        і    ДВОЙНОЕ СЛОВО    іESP і
і   ГДДДДДДДДДДДДДДДДДДДДґ        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   АДДДДДДДДДДДДДДДДДДДДЩ        АДДДДДДДДДДДДДДДДДДДДДЩ     і
і                                                             і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                   Рисунок 3-1. Команда PUSH.
PUSHA (Разместить/поместить все регистры) сохраняет содержимое
восьми регистров общего назначения в стеке (см. Рисунок 3-2).
Эта команда упрощает вызовы процедур путем сокращения числа
команд, необходимых для сохранения содержимого регистров общего
назначения. Процессор размещает регистры общего назначения в
стеке в следующем порядке : EAX, ECX, EDX, EBX, начальное
значение регистра ESP перед тем, как был размещен регистр EAX,
EBP, ESI И EDI. Результат выполнения команды PUSHA
противоположен действию команды POPA.
POP (Восстановить (данные) из стека) передает слово или двойное
слово из текущей вершины стека (на которую указывает регистр
ESP) операнду назначения и затем увеличивает значение регистра
ESP, чтобы тот указывал на новую вершину стека. Смотри Рисунок 3
-3. POP перемещает информацию из стека в регистр общего
назначения, регистр сегмента или в память. Для передачи двойного
слова из стека в регистр общего назначения используется
специальная форма команды POP. Эта форма кодируется кодом,
который на один байт короче, чем кодирование общей формы
команды.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і                                                             і
і  ПЕРЕД ВЫПОЛНЕНИЕМ КОМАНДЫ    ПОСЛЕ ВЫПОЛНЕНИЯ КОМАНДЫ      і
і          PUSHA                         PUSHA                і
і                                                             і
і   31                   0        31                    0     і
і   ЪДДДДДДДДДДДДДДДДДДДДї        ЪДДДДДДДДДДДДДДДДДДДДДї     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        ГДДДДДДДДДДДДДДДДДДДДДґ     і  
                   і     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   і                    іESP    ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        і        EAX          і     і
і   і                    і        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        і        ECX          і     і
і   і                    і        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        і        EDX          і     і
і   і                    і        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        і        EBX          і     і
і   і                    і        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        і СТАРОЕ ЗНАЧЕНИЕ ESP і     і
і   і                    і        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        і        EBP          і     і
і   і                    і        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        і        ESI          і     і
і   і                    і        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        і        EDI          іESP і
і   ГДДДДДДДДДДДДДДДДДДДДґ        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   ГДДДДДДДДДДДДДДДДДДДДґ        ГДДДДДДДДДДДДДДДДДДДДДґ     і
і   АДДДДДДДДДДДДДДДДДДДДЩ        АДДДДДДДДДДДДДДДДДДДДДЩ     і
і                                                             і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                  Рисунок 3-2. Команда PUSHА.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і                                                             і
і    ПЕРЕД ВОССТАНОВЛЕНИЕМ       ПОСЛЕ ВОССТАНОВЛЕНИЯ         і
і       ДВОЙНОГО  СЛОВА             ДВОЙНОГО  СЛОВА           і
і                                                             і
і   31                    0      31                   0       і
і   ЪДДДДДДДДДДДДДДДДДДДДДї      ЪДДДДДДДДДДДДДДДДДДДДї       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      і                    іESP   і
і   і    ДВОЙНОЕ СЛОВО    іESP  ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   АДДДДДДДДДДДДДДДДДДДДДЩ      АДДДДДДДДДДДДДДДДДДДДЩ       і
і                                                             і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                   Рисунок 3-3. Команда POP.
POPA (Восстановить (из стека) все регистры)  восстанавливает  из
стека  данные,  сохраненные  в  нем  при помощи команды PUSHA, в
регистры  общего  назначения,  за  исключением   регистра   ESP.
Значение  регистра ESP восстанавливается после выполнения чтения
стека (Восстановления).  Смотри Рисунок 3-4.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і                                                             і
і  ПЕРЕД ВЫПОЛНЕНИЕМ КОМАНДЫ      ПОСЛЕ ВЫПОЛНЕНИЯ КОМАНДЫ    і
і          POPA                           POPA                і
і                                                             і
і   31                    0      31                   0       і
і   ЪДДДДДДДДДДДДДДДДДДДДДї      ЪДДДДДДДДДДДДДДДДДДДДї       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      ГДДДДДДДДДДДДДДДДДДДДґ       і  
                   і     і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      і                    іESP   і
і   і        EAX          і      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      і                    і       і
і   і        ECX          і      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      і                    і       і
і   і        EDX          і      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      і                    і       і
і   і        EBX          і      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      і                    і       і
і   і СТАРОЕ ЗНАЧЕНИЕ ESP і      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      і                    і       і
і   і        EBP          і      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      і                    і       і
і   і        ESI          і      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      і                    і       і
і   і        EDI          іESP  ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   ГДДДДДДДДДДДДДДДДДДДДДґ      ГДДДДДДДДДДДДДДДДДДДДґ       і
і   АДДДДДДДДДДДДДДДДДДДДДЩ      АДДДДДДДДДДДДДДДДДДДДЩ       і
і                                                             і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                   Рисунок 3-4. Команда POPA.
3.1.3 Команды преобразования типов.
----------------------------------------------------------------
Команды преобразования типа преобразуют байты в слова, слова в
двойные слова и двойные слова в 64-разрядные значения (так
называемые учетверенные слова). Эти команды особенно полезны при
преобразовании целых со знаком, поскольку они автоматически
заполняют дополнительные биты большего элемента значениями
знакового бита меньшего элемента. Это приводит к целым того же
знака и той же величины, только в более длинном формате. Такой
тип преобразования, показанный на Рисунке 3-5, называется
распространением знака.
Имеется два вида команд преобразования типа :
- Команды CWD, CBW и CWDE, которые работают только с данными в
  регистре EAX.
- Команды MOVSX и MOVZX, которые позволяют одному из операндов
  быть регистром общего назначения, оставляя другому операнду
  возможность быть ячейкой памяти или регистром.
CWD (Преобразовать слово в двойное слово) и CDQ (Преобразовать
двойное слово в учетверенное слово) удваивают размерность
операнда-источника. Команда CWD копирует знак (бит 15) слова в
регистре AX в каждый бит регистра DX. Команда CDQ копирует знак
(бит 31) двойного слова в регистре EAX в каждый бит регистра
EDX. Команда CWD может быть использована для получения делимого
в формате двойного слова из слова перед началом деления слова, и
команда CDQ может быть использована для получения делимого в
формате учетверенного слова из двойного слова перед началом
деления двойного слова.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Дї
і                                                                
 і
і                                15                              
0і
і                                ЪДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВД
їі
і  ДО РАСШИРЕНИЯ ЗНАКА           іSіNіNіNіNіNіNіNіNіNіNіNіNіNіNіN
іі
і                                АДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБД
Щі
і                                                                
 і
і                                                                
 і
і31                                                              
0і
іЪДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВДВД
їі
ііSіSіSіSіSіSіSіSіSіSіSіSіSіSіSіSіSіNіNіNіNіNіNіNіNіNіNіNіNіNіNіN
іі
іАДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБДБД
Щі
і  ПОСЛЕ РАСШИРЕНИЯ ЗНАКА                                        
 і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
ДЩ
              Рисунок 3-5. Распространение знака.
CBW  (Преобразовать  байт в слово) копирует знак (бит 7) байта в
регистре AL в каждый бит регистра AX.
CWDE (Преобразовать слово в двойное слово с расширением) копирует
знак (бит 15) слова в регистре AX в каждый бит регистра EAX.
MOVSX (Переслать с распространением знака) расширяет 8-разрядное
значение до 16-разрядного значения или 8-разрядное или
16-разрядное значение до 32-разрядного значения, используя
значение знакового бита для заполнения пустых позиций.
MOVZX (Переслать с расширением нулями) расширяет  8-разрядное
значение   до   16-разрядного   значения   или  8-разрядное  или
16-разрядное  значение   до   32-разрядного   значения,   очищая
(заполняя нулями) пустые позиции.
3.2 Команды двоичной арифметики.
----------------------------------------------------------------
Арифметические команды процессора i486 работают с числовыми
данными, кодированными в двоичном виде. Операции включают
сложение, вычитание, умножение и деление, а также
инкрементирование и декрементирование, сравнение и изменение
знака (инвертирование). Поддерживаются как двоичные целые со
знаком, так и двоичные без знака. Команды двоичной арифметики
могут использоваться также в качестве этапов в арифметических
вычислениях с десятичными целыми. Операнды-источники могут быть
непосредственными значениями, регистрами общего назначения или
данными в памяти. Операнды назначения могут быть регистрами
общего назначения или ячейками памяти (за исключением ситуации,
когда операнд-источник содержится в ячейке памяти). Основные
арифметические команды имеют специальный формат для случая,
когда операндом-источником является непосредственное значение, а
операндом назначения является регистр AL или EAX. Эти форматы
имеют длину на один байт короче, чем арифметические команды
общего вида.
Арифметические команды обновляют значения флагов ZF, CF, SF и
OF, отражающих вид полученного результата. Вид команды,
используемый для проверки флагов, зависит от того, как
интерпретируются данные - как имеющие знак или как не имеющие
знака. Флаг CF содержит информацию, относящуюся к целым без
знака; флаги SF и OF содержат информацию, относящуюся к целым со
знаком. Флаг ZF содержит информацию, касающуюся как целых со
знаком, так и целых без знака: флаг ZF получает значение 1
(устанавливается), когда все биты результата очищаются
(становятся равными 0).
Арифметические команды работают с 8-, 16-, или 32-разрядными
данными. Флаги обновляются в зависимости от размеров операций.
Например, 8-разрядная команда ADD устанавливает флаг CF равным
1, если сумма операндов превышает 255 (десятичное).
Если используется целое без знака, CF флаг может быть проверен
после этих арифметических операций для того, чтобы определить,
когда операция требует переноса или заема единицы разряда для
того, чтобы перейти к следующему этапу операции. Флаг CF
устанавливается в 1, если появляется перенос (в командах
сложения ADD, ADC, AAA и DAA) или заем единицы (в командах
вычитания SUB, SBB, AAS, DAS, CMP и NEG).
Команды INC и DEC не изменяют состояния флага CF. Это позволяет
использовать команды для обновления счетчиков, используемых для
управления циклами без изменения имеющегося состояния
арифметических результатов. Чтобы определить арифметическое
состояние счетчика, можно проверить состояние флага ZF (для
обнаружения окончания цикла) или использовать команды ADD и SUB
для обновления значения, хранящегося в счетчике.
Флаги SF и OF поддерживают целочисленную арифметику со знаком.
Флаг SF имеет значение знакового бита результата. Старшим
значащим битом (MSB) значения целого со знаком является бит,
следующий за знаковым битом - бит 6 байта, бит 14 слова, или бит
30 двойного слова. Флаг OF устанавливается равным 1 в одном из
двух случаев :
- Был порожден перенос из MSB в знаковый бит, но никакого
  переноса из знакового бита не было выполнено (команды сложения
  ADD, ADC, INC, AAA, и DAA). Другими словами, результат был
  больше, чем максимальное положительное число, которое может
  быть представленно в двоичном дополнительном коде.
- Был порожден перенос из знакового бита в MSB, но никакого
  переноса из знакового бита не было выполнено (команды
  вычитания SUB, SBB, DEC, AAS, DAS, CMP и NEG). Другими
  словами, результат оказался меньше, чем наименьшее
  отрицательное число, которое может быть представлено в
  двоичном дополнительном коде.
Эти флаги статуса проверяются обоими типами условных команд: Jcc
(переход по условию cc) или SETcc (установка байта по условию).
3.2.1 Команды сложения и вычитания.
----------------------------------------------------------------
ADD (Сложение целых) заменяет операнд назначения на сумму
операнда-источника и операнда назначения. Команда оказывает
воздействие на флаги OF, SF, ZF, AF, PF и CF.
ADC (Сложение целых с переносом) заменяет операнд назначения на
сумму операнда-источника и операнда назначения плюс 1, если флаг
CF установлен. Если флаг CF сброшен, команда ADC выполняет те же
действия, что и команда ADD. Команда ADC используется для
поддержки переноса, когда сложение выполняется на одном из
этапов, например, когда используется 32-разрядная команда ADD
для сложения двух учетверенных слов-операндов. Команда оказывает
воздействие на флаги OF, SF, ZF, AF, PF, и CF.
INC (Инкременирование) добавляет 1 к операнду назначения.
Команда INC сохраняет значение флага CF. Это позволяет
использовать команду INC для обновления счетчиков циклов без
оказания воздействия на флаги состояния, изменяющиеся под
воздействием арифметических операций, используемых при
управлении циклом. Флаг ZF может быть использован для
обнаружения ситуации возникновения переноса. Использование
команды ADD с непосредственным значением 1 в качестве операнда
выполняет увеличение с обновлением флага CF. Можно использовать
однобайтную форму этой команды, когда операндом является регистр
общего назначения. Команда оказывает воздействие на флаги OF,
SF, ZF, AF, и PF.
SUB (Вычитание целых) вычитает операнд-источник из
операнда назначения и заменяет значение операнда назначения на
полученный результат. Если возникает заем единицы,
устанавливается значение флага CF. Операндами могут быть байты,
слова и двойные слова со знаком и без него. Команда оказывает
воздействие на флаги OF, SF, ZF, AF, PF и CF.
SBB (Вычитание целых с заемом) вычитает операнд-источник из
операнда назначения, заменяя значение преемника на результат
вычитания минус 1, если установлен флаг CF. Если флаг CF очищен,
команда SBB выполняет ту же операцию, что и команда SUB. Команда
SUB используется для поддержки заема разряда, когда выполняется
вычитание чисел как один из этапов, например, когда используется
32-разрядная команда SUB для вычитания одного учетверенного
слова из другого. Команда оказывает воздействие на флаги OF, SF,
ZF, AF, PF и CF.
DEC (Декременирование) вычитает 1 из операнда назначения.
Команда DEC сохраняет состояние флага CF. Это позволяет
использовать команду DEC для обновления счетчиков циклов без
воздействия на состояние флагов, изменяемых под воздействием
арифметических операций, используемых для управления циклом.
Использование команды SUB с непосредственным значением 1 в
качестве операнда выполняет уменьшение, которое обновляет
значение флага CF. Допустима однобайтная форма этой команды,
когда операндом является регистр общего назначения. Команда
оказывает воздействие на флаги OF, SF, ZF, AF, и PF.
3.2.2 Команды сравнения и изменения знака.
----------------------------------------------------------------
CMP (Сравнить) вычитает источник из преемника. Команда обновляет
флаги OF, SF, ZF, AF, CF, но не изменяет значения
операнда-источника и операнда назначения. Последующие команды
Jcc и SETcc могут проверять флаги.
NEG (Инвертировать) вычитает целое со знаком из нуля.
Результатом работы команды NEG является изменение знака операнда
в двоичном дополнительном коде при сохраняении его значения.
Команда оказывает воздействие на флаги OF, SF, ZF, AF, PF и CF.
3.2.3 Команды умножения.
----------------------------------------------------------------
Процессор i486 разделяет умножение операндов со знаком и
операндов без знака. Команда MUL работает с целыми без знака, в
то время как команда IMUL работает как с целыми со знаком, так и
с целыми без знака.
MUL (Умножение целых без знака) выполняет умножение без знака
операнда-источника и регистра AL, AX или EAX. Если источником
является байт, процессор умножает его на значение, хранящееся в
регистре AL и возвращает результат удвоенной длины в регистры AH
и AL. Если исходный операнд является словом, процессор умножает
его на значение, хранящееся в регистре AX и возвращает результат
удвоенной длины в регистры DX и AX. Если операнд-источник
является двойным словом, процессор умножает его на значение,
хранящееся в регистре EAX и возвращает результат в виде
учетверенного слова в регистры EDX и EAX. Команда MUL
устанавливает флаги CF и OF, если старшая половина результата
отлична от нуля; в противном случае флаги очищаются. Состояние
флагов SF, ZF, AF и PF неопределено.
IMUL (Умножение целых со знаком) выполняет операцию умножения со
знаком. Команда IMUL имеет три формы :
1. Форма с одним операндом. Операнд может быть словом, байтом
   или двойным словом, расположенным в памяти или в регистре
   общего назначения. Эта команда использует регистры EAX и EDX
   как операнды по умолчанию тем же образом, что и команда MUL.
2. Форма с двумя операндами. Одним из исходных операндов должен
   быть регистр общего назначения, другим операндом может быть
   как регистр общего назначения, так и ячейка памяти. Результат
   заменяет содержимое регистра общего назначения.
3. Форма с тремя операндами : два операнда являются источниками,
   третий операнд является преемником. Одним из
   операндов-источников является непосредственное значение,
   указанное в команде; вторым может быть регистр общего
   назначения или ячейка памяти. Результат сохраняется в
   регистре общего назначения. Непосредственный операнд является
   целым со знаком в двоично-дополнительном коде. Если
   непосредственный операнд является байтом, процессор
   автоматически расширяет его со знаком до размера второго
   операнда, прежде чем выполнить умножение.
Во многих отношениях вышеприведенные три формы похожи :
- Длина результата равняется удвоенной длине операндов.
- Флаги CF и OF устанавливаются, когда значащие биты переносятся
  в старшую половину результата. Флаги CF и OF очищаются, когда
  старшая часть результата является продолжением знака младшей
  части результата. Состояние флагов SF, ZF, AF и PF
  неопределено.
Тем не менее, форматы 2 и 3 отличаются, так как разультат
усекается до длины операндов, прежде чем он он будет сохранен в
регистре назначения. По причине такого усечения необходимо
проверить флаг OF, чтобы быть уверенным, что ни один из значащих
битов не потерян. (Чтобы ознакомиться со способами проверки
флага OF, смотри команды JO, INTO и PUSHF).
Форматы 2 и 3 команды IMUL также могут быть использованы с
операндами без знака, так как вне зависимости от того, являются
ли операнды целыми со знаком или без знака, младшая половина
результата остается одной и той же. Однако флаги CF и OF не
могут быть использованы, для того чтобы определить, отличается
ли правая часть результата от 0.
3.2.4 Команды деления
----------------------------------------------------------------
Процессор i486 подразделяет команды деления на операции деления
с операндами со знаком и с операндами без знака. Команда DIV
работает с целыми без знака, в то время как команда IDIV
работает как с целыми со знаком, так и с целыми без знака. В
обоих случаях генерируется исключение ошибки деления, если
делитель равен 0 или частное слишком велико для регистров AL, AX
и EAX.
DIV (Деление целых без знака) выполняет беззнаковое деление
регистров AL, AX и EAX на операнд-источник. Делимое
(аккумулятор) по длине в два раза больше, чем делитель (операнд-
источник); частное и остаток имеют ту же длину, что и делитель,
как показано в Таблице 3-1.
Нецелочисленные результаты усекаются в направлении 0. Остаток
всегда меньше, чем делитель. Для деления байтов без знака
наибольшим частным может быть число 255. Для деления слов без
знака наибольшее частное равняется 62535. Для деления двойных
слов наибольшее частное равно 2**32-1. Состояние флагов OF, SF,
ZF, AF, PF и CF неопределено.
               Таблица 3-1. Ореранды команд деления
ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДВДДДДДДДДДДДДДДВДДДДДДДДДДДДДї
і Размер  операнда і   Делимое   і   Частное    і   Остаток   і
і  (Делитель)      і             і              і             і
ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДЕДДДДДДДДДДДДДДЕДДДДДДДДДДДДДґ
і   Байт           і Регистр AX  і Регистр AL   і Регистр AH  і
і   Слово          і DX и AX     і Регистр AX   і Регистр DX  і
і   Двойное слово  і EDX и EAX   і Регистр EAX  і Регистр EDX і
АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДБДДДДДДДДДДДДДДБДДДДДДДДДДДДДЩ
IDIV (Деление целых со знаком) выполняет деление со знаком
сумматора на операнд-источник. Команда IDIV использует те же
регистры, что и команда DIV.
Для  деления байтов со знаком максимальное положительное частное
равняется  +127,  минимальное  отрицательное  частное  равняется
-128.   Для  деления  слов  со знаком максимальное положительное
частное  равняется  +32767,  минимальное  отрицательное  частное
равняется   -32768.    Для   деления   двойных  слов  со  знаком
максимальное   положительное   частное    равняется    +2**32-1,
минимальное     отрицательное    частное    равняется    -2**31.
Нецелочисленные результаты усекаются в направлении  0.   Остаток
всегда имеет тот же знак, что и частное и меньше, чем делитель в
выражении.   Состояние  флагов  OF,  SF,  ZF,  AF,   PF   и   CF
неопределено.
3.3  Команды десятичной арифметики
----------------------------------------------------------------
Десятичные арифметические вычисления выполняются путем
комбинирования команд двоичной арифметики (уже описанных в
предыдущем разделе) и команд десятичной арифметики. Команды
десятичной арифметики используются одним из следуюших способов :
- Преобразуют результаты ранее выполненных двоичных
  арифметических операций, чтобы получить допустимые упакованные
  или неупакованные десятичные результаты.
- Преобразуют входные данные для подпоследовательности двоичных
  арифметических операций таким образом, чтобы операции выдавали
  допустимые упакованные или неупакованные десятичные
  результаты. Эти команды работают только с регистрами AL или
  AH. Большинство использует флаг AL.
3.3.1 Команды коррекции упакованного BCD
----------------------------------------------------------------
DAA (Десятичная коррекция после сложения) корректирует результат
сложения двух допустимых упакованных десятичных операндов в
регистре AL. Команда DAA должна следовать за сложением двух пар
упакованных десятичных чисел (одна цифра в каждой половине
байта) для получения пары правильно упакованных десятичных цифр
в качестве результатов. Флаг CF устанавливается в случае
возникновения переноса. Изменяется значение флагов SF, ZF, AF,
PF и CF. Состояние флага OF неопределено.
DAS (Десятичная коррекция после вычитания) корректирует
результат вычитания двух значащих упакованных десятичных
операндов в регистре AL. Команда DAS всегда должна следовать за
вычитанием одной пары упакованных десятичных чисел (одна цифра в
каждой половине байта) из другой пары для получения пары
правильно упакованных десятичных цифр в качестве результата.
Флаг CF устанавливается, если возникает необходимость заема
разрядной единицы. Изменяется значение флагов SF, ZF, AF, PF и
CF. Состояние флага OF неопределено.
3.3.2 Команды коррекции неупакованного BCD
----------------------------------------------------------------
AAA (ASCII-коррекция после сложения) изменяет содержимое
регистра AL на допустимое неупакованное десятичное число и
очищает старшие 4 бита. Команда AAA должна следовать за
сложением двух неупакованных десятичных операндов в регистре AL.
Устанавливается флаг CF и увеличивается значение регистра AH в
случае возникновения переноса. Изменяется значение флагов AF и
CF. Состояние флагов OF, SF, ZF и PF неопределено.
AAS (ASCII-коррекция после вычитания) изменяет содержимое
регистра AL на значащее неупакованное десятичное число и очищает
старшие 4 бита. Команда AAS должна следовать за вычитанием
одного неупакованного десятичного операнда из другого в регистре
AL. Устанавливается флаг CF и уменьшается значение регистра AH,
если необходим заем разряда. Изменяются значения флагов AF и CF.
Состояние флагов OF, SF, ZF и PF неопределено.
AAM (ASCII-коррекция после умножения) корректирует результат
умножения двух значащих неупакованных десятичных чисел. Команда
AAM должна следовать за умножением двух десятичных чисел, чтобы
получить значащий десятичный результат. Старшая цифра
расположена слева в регистре AH, младшая цифра расположена в
регистре AL. Изменяются значения флагов SF, ZF и PF. Состояние
флагов AF, OF и CF неопределено.
AAD (ASCII-коррекция перед делением) модифицирует делимое в
регистрах AH и AL, чтобы подготовиться к делению двух значащих
неупакованных десятичных операндов так, чтобы частное от деления
было бы допустимым неупакованным десятичным числом. Регистр AH
должен содержать старшую цифру и регистр AL должен содержать
младшую цифру. Эта команда округляет значение и помещает
результат в регистр AL. Регистр AH очищается. Изменяются
значения регистров SF, ZF и PF. Состояное регистров AF, OF и CF
неопределено.
3.4 Логические команды.
----------------------------------------------------------------
Логические команды имеют два операнда. Операнд-источник может
быть непосредственным значением, регистром общего назначения или
ячейкой памяти. Операнды назначения могут быть регистрами общего
назначения или ячейками памяти (за исключением ситуации, когда
источник является ячейкой памяти). Логические команды изменяют
состояние флагов. Возможно применение кратких форм команд, если
непосредственное значение операнда-источника применяется к
операнду назначения в регистрах AL или EAX. Группы логических
операций включают в себя :
- Команды булевых операций.
- Команды проверки и модификации битов.
- Команды сканирования битов.
- Команды сдвига и циклического сдвига.
- Установка значения байта по условию.
3.4.1 Команды булевых операций.
----------------------------------------------------------------
Логические операции выполняются командами AND, OR, XOR и NOT.
NOT (Отрицание) инвертирует биты в указанном операнде в форме
дополнения до единицы. Команда NOT является унарной операцией,
которая использует один операнд в регистре или в ячейке памяти.
NOT не влияет на флаги.
Команды AND, OR и XOR выполняют стандартные логические операции
"and", "or" и "исключающее or". Эти команды могут использовать
следующие комбинации операндов :
- Два регистровых операнда.
- Операнд - регистр общего назначения и операнд - ячейка памяти.
- Операнд - непосредственное значение и либо регистр общего
назначения, либо операнд - ячейка памяти.
Команды AND, OR и XOR очищают флаги OF и CF, оставляя флаг AF
неопределенным и обновляя флаги SF, ZF И PF.
3.4.2 Команды проверки и модификации битов.
----------------------------------------------------------------
Эта группа команд работает с одним битом, который может
находиться в памяти или в регистре общего назначения. Положение
бита задается в виде смещения относительно младшего бита
операнда. Значение смещения может задаваться в виде
непосредственного значения или содержаться в регистре общего
назначения.
Описываемые команды вначале присваивают значение выбранного бита
флагу CF. Затем выбранному биту присваивается новое значение,
которое определяется каждой конкретной операцией. Состояние
флагов OF, SF, ZF, AF и PF не определено. Значения, помещаемые в
выбранный бит данными командами приведены в Таблице 3-2.
3.4.3 Команды сканирования битов
Эти команды сканируют слово или двойное слово в поисках
установленного бита и заносят в регистр номер первого
установленного бита (целое число, определяющее позицию
найденного бита). Сканируемая строка может находиться как в
регистре, так и в памяти. Если все слово равно нулю, т.е. в нем
нет единичных битов, устанавливается флаг ZF. Если единичный бит
найден, флаг ZF очищается. Если единичных битов не найдено,
значение регистра назначения не определено. Состояние
флагов OF, SF, ZF, PF и CF не определено.
BSF (Сканирование битов вперед) просматривает биты от младшего к
старшему (от бита 0 до старшего бита).
BSR (Сканирование битов в обратном порядке) просматривает биты
от старшего к младшему (от самого старшего бита к биту 0).
      Таблица 3-2. Команды проверки и модификации битов.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДї
і         Команда            і    Значение    і    Значение    і
і                            і    флага CF    івыбранного бита і
ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДґ
і BT (проверка бита)         і  Флаг CF      і  Не оказывает  і
і                            і Выбранный бит  і     влияния    і
і BTS (проверка и            і     --"--      іВыбранный бит1 і
і      установка бита)       і                і                і
і BTR (проверка и            і     --"--      іВыбранный бит0 і
і      сброс бита)           і                і                і
і BTC (проверка и задание    і     --"--      іВыбранный бит  і
і противоположного значения) і                і-(Выбранный бит)і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДЩ
3.4.4 Команды смещения (сдвига) и циклического сдвига
----------------------------------------------------------------
Команды сдвига и циклического сдвига  переставляют  биты  внутри
операнда.  Эти команды подразделяются на три класса :
- Команды сдвига.
- Команды двойного сдвига.
- Команды циклического сдвига.
3.4.4.1 Команды сдвига
----------------------------------------------------------------
Команды  сдвига  выполняют арифметический или логический сдвиг
над байтами, словами или двойными словами.  Арифметический сдвиг
вправо  копирует  знаковый  бит  в  пустую позицию старшего бита
операнда, в  то  время  как  логический  сдвиг  вправо,  сдвинув
операнд вправо, очищает пустые позиции. Арифметический сдвиг
является самым быстрым способом выполнения простейших
вычислений. Например, арифметический сдвиг вправо на один бит
выполняет деление целого на два. Логический сдвиг делит целое
без знака или положительное целое, но отрицательное целое со
знаком теряет свой знаковый бит.
Команды арифметического и логического сдвига вправо, SAR и SHR,
отличаются друг от друга только своей интерпретацией позиций
битов, освобождаемых при смещении содержимого операндов.
Обратите внимание, что нет различий в командах логического и
арифметического сдвига влево. Два символьных имени, SAL и SHL,
поддерживаются языком ассемблера для обозначения одной команды.
Счетчик указывает число битовых позиций, на которое надо
сдвинуть операнд. Биты могут быть сдвинуты максимум на 31
позицию. Команды сдвига могут задавать счетчик сдвига любым из
трех способов. Одна форма команд сдвига всегда выполняет сдвиг
на один бит. Вторая форма задает счетчик сдвига как
непосредственное значение. Третья форма задает счетчик как
значение, содержащееся в регистре CL. Последняя форма позволяет
задавать счетчик как результат вычислений. Используются только
пять младших битов (разрядов) регистра CL.
Когда количество позиций сдвига равно нулю, никакие флаги не
подвергаются изменениям. В противном случае флаг CF заполяется
значением последнего бита, вытесненного за границы операнда. В
командах сдвига на один бит флаг OF устанавливается равным
единице, если значение самого старшего бита (знакового бита)
изменяется в процессе операции. В противном случае флаг OF
очищается (присваивается значение ноль). После сдвига более чем
на одну позицию значение флага OF не определено. При сдвиге на
одну или более позиций изменяются значения флагов SF, ZF, PF и
CF, и состояние флага AF не определено.
SAL (Арифметический сдвиг влево) сдвигает байт, слово или
двойное слово операнда назначения влево на одну позицию или на
количество битов, заданное в операнде-счетчике (непосредственное
значение или значение в регистре CL). Пустые биты очищаются.
Смотри Рисунок 3-6.
SHL (Логический сдвиг влево) другое наименование команды SAL.
Название поддерживается в языке ассемблера.
SHR (Логический сдвиг вправо) сдвигает байт, слово или двойное
слово операнда назначения вправо на одну позицию или на
количество битов, заданное в операнде-счетчике (непосредственное
значение или значение в регистре CL). Пустые биты очищаются.
Смотри Рисунок 3-7.
SAR  (Арифметический  сдвиг  вправо)  сдвигает  байт,  слово или
двойное слово операнда назначения вправо на одну позицию или на
количество битов, заданное в операнде-счетчике (непосредственное
значение или значение в регистре CL). Знак операнда сохраняется
путем очистки пустых позиций битов, если операнд положительный,
или установки значений пустых битов (равным единице), если
операнд отрицательный. Смотри Рисунок 3-8.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і                                                             і
і Начальное состояние :                                       і
і                                                             і
і    CF                        ОПЕРАНД                        і
і   ЪДї           ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї          і
і   іxі           і10001000100010001000100010001111і          і
і   АДЩ           АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ          і
і                                                             і
і После выполнения 1-разрядной (1-битовой) команды SHL/SAL :  і
і                                                             і
і    CF                        ОПЕРАНД                        і
і   ЪДї           ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї          і
і   і1і           і00010001000100010001000100011110і <Д 0     і
і   АДЩ           АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ          і
і                                                             і
і После выполнения 10-разрядной (10-битовой) команды SHL/SAL :і
і                                                             і
і    CF                        ОПЕРАНД                        і
і   ЪДї           ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї          і
і   і0і           і00100010001000100011110000000000і <Д 0     і
і   АДЩ           АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ          і
і                                                             і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                Рисунок 3-6. Команда SHL/SAL.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і                                                             і
і Начальное состояние :                                       і
і                                                             і
і                           ОПЕРАНД                    CF     і
і              ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї     ЪДї     і
і              і10001000100010001000100010001111і     іxі     і
і              АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ     АДЩ     і
і                                                             і
і После выполнения 1-разрядной (1-битовой) команды SHR :      і
і                                                             і
і                           ОПЕРАНД                    CF     і
і              ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї     ЪДї     і
і     0 ДД>    і01000100010001000100010001000111і Д-> і1і     і
і              АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ     АДЩ     і
і                                                             і
і После выполнения 10-разрядной (10-битовой) команды SHR :    і
і                                                             і
і                           ОПЕРАНД                    CF     і
і              ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї     ЪДї     і
і     0 ДД>    і00000000001000100010001000100010і ДД> і0і     і
і              АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ     АДЩ     і
і                                                             і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                Рисунок 3-7. Команда SHR.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і                                                             і
і Начальное состояние (положительный операнд) :               і
і                                                             і
і                         ОПЕРАНД                    CF       і
і            ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї     ЪДї       і
і            і01000100010001000100010001000111і     іxі       і
і            АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ     АДЩ       і
і                                                             і
і После выполнения 1-разрядной (1-битовой) команды SАR :      і
і                                                             і
і                         ОПЕРАНД                    CF       і
і            ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї     ЪДї       і
і         ЪД>і00100010001000100010001000100011і Д-> і1і       і
і         і  АВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ     АДЩ       і
і         АДДДЩ                                               і
і                                                             і
і Начальное состояние (отрицательный операнд) :               і
і                                                             і
і                         ОПЕРАНД                    CF       і
і            ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї     ЪДї       і
і            і11000100010001000100010001000111і     іxі       і
і            АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ     АДЩ       і
і                                                             і
і После выполнения 1-разрядной (1-битовой) команды SАR :      і
і                                                             і
і                         ОПЕРАНД                    CF       і
і            ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї     ЪДї       і
і         ЪД>і11100010001000100010001000100011і Д-> і1і       і
і         і  АВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ     АДЩ       і
і         АДДДЩ                                               і
і                                                             і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                Рисунок 3-8. Команда SАR.
Насмотря на то, что эта команда может быть использована для
деления целых на целое, являющееся степенью двойки, результат
деления не будет тем же, что при выполнении команды IDIV.
Частное при выполнении команды IDIV округляется в сторону нуля,
в то время как "частное" при выполнении команды SAR округляется
в сторону отрицательной бесконечности. Разница проявляется
только для отрицательных чисел. Например, когда используется
команда IDIV для деления -9 на 4, результатом будет -2 с
остатком -1. Если использовать команду SAR для сдвига -9 вправо
на два бита, результатом будет -3. "Остатком" такого вида
деления будет -13; однако команда SAR сохраняет только бит
старшего разряда остатка (во флаге CF).
3.4.4.2 Команды двойного сдвига.
----------------------------------------------------------------
Эти команды обеспечивают основные операции, необходимые для
выполнения действий над длинными невыровненными битовыми
строками. Команды двойного сдвига выполняются как над словами,
так и над двойными словами следующим образом :
- Берутся два операнда длиной в слово и получается результат
  длиной в слово (32-разрядный сдвиг).
- Берутся два операнда длиной в двойное слово и получается
  результат длиной в двойное слово (64-разрядный сдвиг).
Из двух операндов, операнд-источник должен быть регистром, в то
время как операнд назначения может быть как регистром, так и
ячейкой памяти. Количество битов, на которое выполняется сдвиг,
может быть задано в регистре CL или непосредственно значением
байта в команде. Биты, вытесненные за границу
операнда-источника, заполняют пустые биты в операнде назначения,
который тоже сдвигается. Сохраняется значение только
операнда-преемника.
Когда выполняется сдвиг на ноль позиций, ни один из флагов не
подвергается изменениям. В противном случае, флагу CF
присваивается значение последнего бита, вытесненного из операнда
назначения, и изменяются значения флагов SF, ZF и PF. При сдвиге
на один разряд флаг OF получает значение "единица", если знак
операнда изменяется, в противном случае флаг OF очищается. При
сдвигах более чем на один бит состояние флага AF неопределено.
SHLD (Двойной сдвиг влево) сдвигает биты операнда назначения
влево, заполняя пустые биты значениями битов, вытесняемых из
операнда-источника (см. Рисунок 3-9). Результат запоминается в
операнде назначения. Операнд-источник не изменяется.
SHRD (Двойной сдвиг вправо) сдвигает биты операнда назначения
вправо, заполняя пустые биты значениями битов, вытесняемых из
операнда-источника (цм. Рисунок 3-10). Результат запоминается в
операнде назначения. Операнд-источник не изменяется.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і                 31                                     0    і
і  ЪДДї           ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї    і
і  іCFі ДДДДДДДД і  Преемник (память или регистр)       іДї і
і  АДДЩ           АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ  і і
і                                                           і і
і          ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і
і          і      31                                     0    і
і          і      ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї    і
і          АДДДДДДі           Источник (регистр)         і    і
і                 АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ    і
і                                                             і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                 Рисунок 3-9. Команда SHLD.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і     31                                     0                і
і     ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї                і
і     і           Источник (регистр)         іДДДДї           і
і     АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ    і           і
іЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ           і
іі                                                            і
іі    31                                     0                і
іі    ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї         ЪДДї   і
іАДДД>і  Преемник (память или регистр)       іДДДДДДДД>іCFі   і
і     АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ         АДДЩ   і
і                                                             і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                 Рисунок 3-10. Команда SHRD.
3.4.4.3 Koманды циклического сдвига.
----------------------------------------------------------------
Команды циклического сдвига выполняют циклическое перемещение
разрядов в байтах, словах и двойных словах. Биты, вытесненные с
одного конца операнда, заносятся в него с другого конца. В
отличие от команд смещения никакие биты не очищаются в процессе
циклического сдвига.
Команды циклического сдвига используют только флаги CF и OF.
Флаг CF может работать в качестве расширения операнда в двух
командах циклического сдвига, позволяющих биту стать
обособленным и затем быть проверенным командами условного
перехода (JC или JNC). Флаг CF всегда содержит значение
последнего бита, вытесненного за пределы операнда в процессе
циклического сдвига, даже если команда не использует флаг CF в
качестве расширения операнда. Состояние флагов SF, ZF, AF и PF
не изменяется.
При циклическом сдвиге на один бит флаг OF устанавливается, если
операция изменяет самый старший бит (знаковый бит)
операнда назначения. Если сохраняется исходное значение знака,
флаг OF очищается. После циклического сдвига более чем на один
бит значение флага OF не определено.
ROL  (Циклический  сдвиг  влево) циклически сдвигает байт, слово
или двойное слово операнда назначения влево на один бит или на
количество битов, заданное в операнде-счетчике (непосредственное
значение или значение, содержащееся в регистре CL). Для каждого
разряда бит, который вытесняется с левого конца операнда,
возвращается в правый конец. Смотри Рисунок 3-11.
ROR (Циклический сдвиг вправо) циклически сдвигает  байт,  слово
или двойное слово операнда назначения вправо на один бит или на
количество битов, заданное в операнде-счетчике (непосредственное
значение или значение, содержащееся в регистре CL). Для каждого
разряда бит, который вытесняется с правого конца операнда,
возвращается в левый конец. Смотри Рисунок 3-12.
RCL (Циклический сдвиг влево через перенос) циклически  сдвигает
байт,  слово  или двойное слово операнда назначения влево на один
бит  или  на  количество  битов,  заданное  в  операнде-счетчике
(непосредственное значение или значение, содержащееся в регистре
CL).
Эта  команда  отличается от ROL тем, что она интерпретирует флаг
CF как  однобитовое  расширение  операнда-преемника  со  стороны
старших  разрядов.  Для каждого разряда бит, который вытесняется
с левого конца операнда, перемещается во флаг CF.  В тоже  время
бит,  содержащийся  во  флаге  CF,  вводится  с  правой стороны.
Смотри Рисунок  3-13.
RCR (Циклический сдвиг вправо через перенос) циклически сдвигает
байт, слово или двойное слово операнда назначения вправо на один
бит или на количество битов, заданное в операнде-счетчике
(непосредственное значение или значение, содержащееся в регистре
CL).
Эта команда отличается от ROR тем, что она интерпретирует флаг
CF как однобитовое расширение операнда-преемника со стороны
младших разрядов. Для каждого разряда бит, который вытесняется с
правого конца операнда, перемещается во флаг CF. В тоже время
бит, содержащийся во флаге CF, вводится с левой стороны. Смотри
Рисунок 3-14.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і               31                                       0    і
і ЪДДї          ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї    і
і іCFіДДДВДДДДДі    Преемник (память или регистр)       іДї і
і АДДЩ    і     АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ  і і
і         і                                                 і і
і         АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
            Рисунок 3-11. Команда ROL.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і       31                                       0            і
і       ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї       ЪДДї і
і ЪДДДД>і    Преемник (память или регистр)       іДДВДДД>іCFі і
і і     АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ  і    АДДЩ і
і і                                                 і         і
і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ         і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
            Рисунок 3-12. Команда ROR.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і
і і                                                         і і
і і             31                                       0  і і
і і      ЪДДї   ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї  і і
і АДДДДДДіCFіДДі    Преемник (память или регистр)       іДЩ і
і        АДДЩ   АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ    і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
            Рисунок 3-13. Команда RCL.
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї  і
і і                                                        і  і
і і     31                                       0         і  і
і і     ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї   ЪДДї  і  і
і АДДДД>і    Преемник (память или регистр)       іДД>іCFіДДЩ  і
і       АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ   АДДЩ     і
АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
            Рисунок 3-14. Команда RCR.
3.4.4.4 Быстрый "bit blt" с использованием команд двойного
        сдвига
----------------------------------------------------------------
Одним из назначений команд двойного сдвига является реализация
перемещения строки битов, с произвольным рассогласованием
битовых строк. Это называется "bit blt" (BIT BLock
Transfer - пересылка блока битов). Простым примером является
перемещение строки битов с произвольного смещения в памяти в
выровненную по двойным словам строку байт. Слева направо в
строке пересылается 32 бита за один раз, если в цикле пересылки
используется двойное смещение.
   MOV   ESI,ScrAddr
   MOV   EDI,DestAddr
   MOV   EBX,WordCnt
   MOV   CL,RelOffset       ; относительное смещение Dest-Src
   MOV   EDI,[ESI]          ; загрузить первое слово источника
   ADD   ESI,4              ; увеличить адрес источника
BltLoop:
   LODS                     ; новая часть в убывающем порядке
                            ; в EAX
   SHLD  EDX,EAX,CL         ; переписать содержимое EDX на
                            ; выровненную вставку
   XCHG  EDX,EAX            ; поменять местами старшее и младшее
                            ; слово
   STOC                     ; записать очередную выровненную
                            ; часть данных
   DEC   EBX                ; уменьшить счетчик цикла
   JNZ   BltLoop
Это простой цикл, позволяющий данным быть перемещенными по
32-разрядным частям с наивысшей возможной скоростью. Без
двойного смещения наилучшим результатом, который может быть
получен, является 16-разрядная пересылка за цикл с
использованием 32-разрядного смещения, и заменой команды XCHG на
команду ROR по 16 бит для замены местами старшего и младшего
слова в регистрах. Более общий цикл, чем приведен выше,
потребует некоторого маскирования первого перемещаемого двойного
слова (перед основным циклом), последнего перемещаемого двойного
слова (после основного цикла), но будет пересылать те же 32 бита
за один цикл, что и программа, приведенная выше.
3.4.4.5 Быстрая вставка и исключение битовых строк.
----------------------------------------------------------------
Команды двойного смещения также делают возможным :
- Быструю вставку битовой строки из регистра в произвольное
  местоположение бита в большей битовой строке в памяти, без
  нарушения битов по обеим сторонам от вставляемых битов.
- Быстрое исключение битовой строки в регистр с произвольного
  местоположения в большей битовой строке в памяти, без нарушения
  битов по обеим сторонам от исключаемых битов.
Следующие примеры программ иллюстрируют вставку и исключение
битов при различных условиях :
1. Вставка битовой строки в память (когда битовая строка длиной
   от 1 до 25 бит, т.е. вставить 4 байта или меньше) :
; Вставить выровненную по правому краю битовую строку из регистра
; в битовую строку в памяти.
; Допущения :
; 1. Основание массива строки выровнено по двойным словам.
; 2. Длина битовой строки задана непосредственно значением и
;    битовое смещение содержится в регистре.
; Регистр ESI содержит выровненную по правому краю битовую
; строку, которую надо вставить.
; Регистр EDI содержит битовое смещение начальной позиции
; подстроки.
; Также используются регистры EAX и ECX.
MOV   ECX,EDI             ; сохранить исходное смещение
SHR   EDI,3               ; разделить смещение на 8 (адрес байта)
AND   CL,7H               ; получить три младших бита смещения
MOV   EAX,[EDI]strg_base  ; переместить строку длиной в двойное
                          ; слово в EAX
RDR   EAX,CL              ; правое выравнивание поля старых
                          ; битов
SHRD  EAX,ESI,длина       ; получили новые биты
ROL   EAX,длина           ; правое выравнивание поля новых битов
ROL   EAX,CL              ; доставить в конечную позицию
MOV   [EDI]strg_base,EAX  ; заменить двойное слово в памяти
2. Вставка битовой строки в память (когда битовая строка длиной
   от 1 до 31 битa, т.е. вставить 5 байт или меньше) :
; Вставить выровненную по правому краю битовую строку из регистра
; в битовую строку в памяти.
; Допущения :
; 1. База массива строки выровнена по двойным словам.
; 2. Длина битовой строки задана непосредственно значением и
;    битовое смещение содержится в регистре.
; Регистр ESI содержит выровненную по правому краю битовую
; строку, которую надо вставить.
; Регистр EDI содержит битовое смещение начальной позиции
; подстроки.
; Также используются регистры EAX, EBX, ECX и EDI.
MOV   ECX,EDI             ; временно сохранить смещение
SHR   EDI,5               ; разделить смещение на 32 (двойное
                          ; слово)
SHL   EDI,2               ; умножить на 4 (адрес байта)
AND   CL,1FH              ; получить пять младших битов смещения
MOV   EAX,[EDI]strg_base  ; переместить младшую строку длиной в
                          ; двойное слово в EAX
MOV   EDX,[EDI]strg_base+4  ; переместить оставшуюся строку
                          ; длиной в двойное слово в EDX
MOV   EBX,EAX             ; временное сохранение части строки
SHRD  EAX,EDX,CL          ; смещение на заданное число бит
                          ; внутри двойного слова
SHRD  EAX,EBX,CL          ; смещение на заданное число бит
                          ; внутри двойного слова
SHRD  EAX,ESI,длина       ; получили новые биты
ROL   EAX,длина           ; правое выравнивание поля новых битов
MOV   EBX,EAX             ; временное сохранение строки
SHLD  EAX,EDX,CL          ; смещение на заданное число бит
                          ; внутри слова
SHLD  EDX,EDX,CL          ; смещение на заданное число бит
                          ; внутри слова
MOV   [EDI]strg_base,EAX  ; заменить двойное слово в памяти
MOV   [EDI]strg_base+4,EDX  ; заменить двойное слово в памяти
3. Вставка битовой строки в память (когда битовая строка длиной
   32 битa, т.е. вставить 4 или 5 байт) :
;  Вставить  выровненную  по  правому  краю  битовую  строку  из
;  регистра в битовую строку в памяти.
;  Допущения :
; 1. База массива строки выровнена по двойным словам.
; 2. Длина  битовой  строки  32  бита  и  битовое   смещение
;  содержится в регистре.
; Регистр ESI содержит 32-битовую строку, которую надо вставить.
; Регистр EDI содержит битовое смещение начальной позиции
; подстроки.
; Также используются регистры EAX, EBX, ECX и EDI.
MOV   EDX,EDI             ; сохранить исходное смещение
SHR   EDI,5               ; разделить смещение на 32 (двойное
                          ; слово)
SHL   EDI,2               ; умножить на 4 (адрес байта)
AND   CL,1FH              ; изолировать пять младших битов
                          ; смещения
MOV   EAX,[EDI]strg_base  ; переместить младшую строку длиной в
                          ; двойное слово в EAX
MOV   EDX,[EDI]strg_base+4  ; переместить оставшуюся строку
                          ; длиной в двойное слово в EDX
MOV   EBX,EAX             ; временное сохранение части строки
SHRD  EAX,EDX             ; смещение на заданное число бит
                          ; внутри двойного слова
SHRD  EDX,EBX             ; смещение на заданное число бит
                          ; внутри двойного слова
MOV   EAX,ESI             ; переместить 32-разрядное поле в
                          ; положение
MOV   EBX,EAX             ; временное сохранение части строки
SHLD  EAX,EDX             ; смещение на заданное число бит
                          ; внутри слова
SHLD  EDX,EBX             ; смещение на заданное число бит
                          ; внутри слова
MOV   [EDI]strg_base,EAX  ; заменить двойное слово в памяти
MOV   [EDI]strg_base+4,EDX  ; заменить двойное слово в памяти
4. Изъятие битовой строки из памяти (когда битовая строка длиной
от 1 до 25 бит, т.е. изъять 4 байта или меньше) :
; Изъять выровненную по правому краю битовую строку в регистр
; из битовой строки в память.
; Допущения :
; 1. База массива строки выровнена по двойным словам.
; 2. Длина битовой строки задана непосредственно значением и
;    битовое смещение содержится в регистре.
; Регистр EAX содержит выровненную по правому краю дополненную
; нулями битовую строку, которую надо изъять.
; Регистр EDI содержит битовое смещение начальной позиции
; подстроки.
; Также используются регистры EDI и ECX.
MOV   ECX,EDI             ; временное сохранение смещения
SHR   EDI,3               ; разделить смещение на 8 (адрес байта)
AND   CL,7H               ; получить три младших бита смещения
MOV   EAX,[EDI]strg_base  ; переместить строку длиной в двойное
                          ; слово в EAX
SHR   EAX,CL              ; смещение на заданное количество
                          ; битов внутри двойного слова
AND   EAX,маска           ; изъять битовое поле в EAX
5. Изъятие битовой строки из памяти (когда битовая строка длиной
от 1 до 32 бит, т.е. изъять 5 байт или меньше) :
; Изъять выровненную по правому краю битовую строку в регистр
; из битовой строки в памяти.
; Допущения :
; 1. База массива строки выровнена по двойным словам.
; 2. Длина битовой строки задана непосредственно значением и
;    битовое смещение содержится в регистре.
; Регистр EAX содержит выровненную по правому краю дополненную
; нулями битовую строку, которую надо изъять.
; Регистр EDI содержит битовое смещение начальной позиции
; подстроки.
; Также используются регистры EAX, EBX и ECX.
MOV   ECX,EDI             ; временно сохранить смещение
SHR   EDI,5               ; разделить смещение на 32 (двойное
                          ; слово)
SHL   EDI,2               ; умножить на 4 (адрес байта)
AND   CL,1FH              ; получить пять младших битов смещения
MOV   EAX,[EDI]strg_base  ; переместить младшую строку длиной в
                          ; двойное слово в EAX
MOV   EDX,[EDI]strg_base+4  ; переместить оставшуюся строку
                          ; длиной в двойное слово в EDX
SHRD  EAX,EDX,CL          ; смещение на заданное число бит
                          ; внутри двойного слова
SHRD  EAX,EDX,CL          ; смещение на заданное число бит
                          ; внутри двойного слова
AND   EAX,маска           ; изъять битовое поле в EAX


Яндекс цитирования