Описание процессора i8086 для программиста

       

при выполнении операции сложения распакованных


Инструкция AAA используется совместно с инструкцией ADD
или ADC
при выполнении операции сложения распакованных двоично-десятичных чисел. Сложение выполняется последовательно – по одному десятичному разряду. Складываемые двоично-десятичные значения перед выполнением команды сложения располагаются в младших полубайтах её операндов, причём один из них – в младшем полубайте регистра AL. Следующая за инструкцией сложения команда коррекции на основании полученного результата и состояния флажка вспомогательного переноса корректирует результат в регистре AL. Флажок CF, установленный после выполнения инструкции AAA, свидетельствует о том, что возник перенос в следующий разряд распакованного двоично-десятичного числа, который должен быть учтён при выполнении следующего прохода сложения.


Инструкция AAD предшествует инструкции DIV
и корректирует делимое, состоящее из двух двоично-десятичных цифр, находящихся в младших полубайтах регистров AH и AL; старшие полубайты при этом должны быть равны нулю. Делитель должен быть двоично-десятичным одноразрядным распакованным числом, т.е. иметь значение от 0 до 9. В результате выполнения команды DIV в регистре AL будет сформировано правильное двоичное частное. Для его преобразования в двоично-десятичный можно воспользоваться инструкцией AAM. Остаток принимает значение 0–9 в зависимости от значения исходных операндов, поэтому не нуждается в дополнительном преобразовании в двоично-десятичный вид.
Фирменные руководства ничего не говорят о том, используются ли при выполнении инструкции AAD значения старших полубайтов регистров AH и AL, поэтому лучше перестраховаться и обеспечить их обнуление.
Инструкция AAD может использоваться для преобразования двухразрядного десятичного числа в двоичное.


Инструкция AAM может использоваться для преобразования двоичного числа без знака в двухразрядное десятичное.


Совместно с командами десятичной коррекции сложения AAA
и DAA


инструкция ADD
обеспечивает сложение двоично-десятичных распакованных и упакованных чисел.
Если необходимо складывать числа с разрядностью, превышающей 16, младшие 16 бит складываются инструкцией ADD, а все последующие – инструкцией ADC.


Команда ADC используется при сложении двоичных чисел с разрядностью, превышающей 16. В этом случае сложение младших частей операндов выполняется с помощью инструкции ADD, а последующих частей операндов – с помощью инструкций ADC, следующих за ADD.
Совместно с командами десятичной коррекции сложения AAA
и DAA
инструкции ADD
и ADC
обеспечивают сложение двоично-десятичных распакованных и упакованных чисел.


При записи на языке ассемблера либо используется мнемоника CMPSB
или CMPSW, явно определяющая размер операндов, либо используется обобщённая мнемоника CMPS
с указанием местоположения операндов в памяти. Следует, однако, помнить, что адресация операндов всегда осуществляется с помощью регистровых пар DS:SI и ES:DI, поэтому указываемые в данной инструкции адреса используются только для определения размера операндов и, возможно, для применения префикса замены сегмента. За правильность установки начальных значений регистров отвечает программист.


Декремент 16- разрядных регистров общего назначения может быть выполнен двумя видами инструкций – однобайтовой (код операции 48 плюс номер регистра) и двухбайтовой (код операции FF, номер регистра определяется байтом ModRegR/M). Транслятор языка ассемблера автоматически генерирует однобайтовый код операции как более компактный; второй вариант при необходимости может быть запрограммирован вручную.


Хотя аппаратная архитектура микропроцессора 8086/8088 позволяла подключить к нему сопроцессор произвольного назначения, был разработан и получил распространение только арифметический сопроцессор 8087. Описание его системы команд не входит в задачу данной публикации.


Инкремент 16- разрядных регистров общего назначения может быть выполнен двумя видами инструкций – однобайтовой (код операции 40 плюс номер регистра) и двухбайтовой (код операции FF, номер регистра определяется байтом ModRegR/M). Транслятор языка ассемблера автоматически генерирует однобайтовый код операции как более компактный; второй вариант при необходимости может быть запрограммирован вручную.


Прерывание по вектору 3 (отладочное) может быть выработано инструкциями двух видов – специальной однобайтовой с кодом CC и общей двухбайтовой CD 03. Трансляторы с языка ассемблера для инструкции INT 3 всегда генерируют код CC; двухбайтовый код CD 03 может быть при необходимости сформирован вручную.
Однобайтовый код операции интенсивно используется отладчиками для формирования точек останова, поскольку позволяет заменить код операции любой команды, в том числе и однобайтовой.


Инструкция INTO обычно размещается после команд, которые могут вызвать установку флажка OF, с целью выработки прерывания при возникновении переполнения.


Многие инструкции условных переходов имеют по несколько мнемоник для одного и того же кода операций. Та или иная мнемоника позволяет точнее указать, какой именно тип анализа с точки зрения человека выполняется командой перехода в данном месте программы, хотя функционально команды с разными мнемониками, на одинаковыми кодами операций абсолютно равнозначны. Например, мнемоника JZ
может быть применена, когда предыдущая инструкция проверяла содержимое какой-либо ячейки памяти на нуль, в то время как мнемоника JE, соответствующая той же самой машинной операции (код операции 74), применяется после инструкции сравнения двух величин. В том и другом случае переход произойдёт, если установлен флажок ZF.
Инструкции, в названии которых содержатся слова “больше” или “меньше”, предназначены для анализа результатов сравнения чисел со знаком, а инструкции, содержащие слова “выше” и “ниже”, предназначены для анализа результатов сравнения беззнаковых чисел. В командах, предназначенных для переходов по результатам сравнения чисел со знаком, анализируются флажки SF и OF, а в командах для беззнаковых сравнений – флажок CF. Равенство или неравенство чисел независимо от наличия у них знака в любом случае отражается состоянием флажка ZF.
Инструкция JCXZ является единственной командой условного перехода, которая не проверяет состояние какого-либо флажка или группы флажков. Вместо этого она проверяет содержимое регистра CX. Поскольку этот регистр используется в качестве счётчика при выполнении строковых операций, инструкция JCXZ дополняет набор префиксов повторения, специально предназначенных для работы совместно с операциями обработки строк. Кроме того, эта команда может использоваться для организации циклов при использовании регистра CX в качестве счётчика итераций вместо инструкции LOOP, когда значение счётчика не уменьшается на 1 при каждом проходе цикла, как то предусмотрено последней командой.


В том случае, когда эффективный адрес однозначно определяется отклонением, вместо команды LEA выгоднее использовать команду MOV с кодом операции B8–BF. Команда MOV
займёт 3 байта памяти вместо 4 и на процессоре 8086 будет выполняться в два раза быстрее (4 такта вместо 8).


При записи на языке ассемблера либо используется мнемоника LODSB
или LODSW, явно определяющая размер операндов, либо используется обобщённая мнемоника LODS
с указанием местоположения операнда в памяти. Следует, однако, помнить, что адресация операнда в памяти всегда осуществляется с помощью регистровой пары DS:SI, поэтому указанный в данной инструкции адрес используется только для определения размера операнда и, возможно, для применения префикса замены сегмента. За правильность установки начальных значений регистров отвечает программист.


При записи на языке ассемблера либо используется мнемоника MOVSB
или MOVSW, явно определяющая размер операндов, либо используется обобщённая мнемоника MOVS
одновременно с указанием местоположения самих операндов в памяти. Следует, однако, помнить, что адресация операндов всегда осуществляется с помощью регистровых пар DS:SI и ES:DI, поэтому указываемые в данной инструкции адреса используются только для определения размера операндов и, возможно, для применения префикса замены сегмента. За правильность установки начальных значений регистров отвечает программист.


Строго говоря, инструкция NOP является инструкцией XCHG AX, AX.


Выполнение инструкции POP SP
приведёт к загрузке в SP слова из старой вершины стека, поскольку увеличение SP на 2 производится после выборки слова из вершины стека, но до занесения этого слова в операнд инструкции.


Выполнение инструкции PUSH SP
приведёт к записи в стек нового содержимого SP, т.е. значения, которое находится в этом регистре после вычитания. В процессоре 80286 и последующих в стек заносится исходное содержимое регистра SP, т.е. его значение до вычитания.


Микропроцессоры 8086 и 8088 не маскируют значение счётчика сдвига. Таким образом, сдвиг может быть выполнен на произвольное число разрядов от 0 до 255. В процессорах, начиная с 80286, в качестве счётчика сдвига используются только младшие 5 разрядов регистра CL, что ограничивает максимальное количество сдвигов (не более 31).


Микропроцессоры 8086 и 8088 не маскируют значение счётчика сдвига. Таким образом, сдвиг может быть выполнен на произвольное число разрядов от 0 до 255. В процессорах, начиная с 80286, в качестве счётчика сдвига используются только младшие 5 разрядов регистра CL, что ограничивает максимальное количество сдвигов (не более 31).


Освобождение стека особенно полезно в том случае, если процедура получает через стек строго определённое число параметров. В этом случае стек может быть очищен вызываемой процедурой, и вызывающая процедура освобождается от лишней работы.
Необходимо строго следить, чтобы длина возврата соответствовала длине вызова процедуры. Например, если для вызова использовалась инструкция длинного перехода, то и возврат должен быть длинным. Нарушение этого правила приведёт к неверному выполнению операции возврата и к разрушению информации в стеке, последствия чего будут непредсказуемыми.


Микропроцессоры 8086 и 8088 не маскируют значение счётчика сдвига. Таким образом, сдвиг может быть выполнен на произвольное число разрядов от 0 до 255. В процессорах, начиная с 80286, в качестве счётчика сдвига используются только младшие 5 разрядов регистра CL, что ограничивает максимальное количество сдвигов (не более 31).


Микропроцессоры 8086 и 8088 не маскируют значение счётчика сдвига. Таким образом, сдвиг может быть выполнен на произвольное число разрядов от 0 до 255. В процессорах, начиная с 80286, в качестве счётчика сдвига используются только младшие 5 разрядов регистра CL, что ограничивает максимальное количество сдвигов (не более 31).


Микропроцессоры 8086 и 8088 не маскируют значение счётчика сдвига. Таким образом, сдвиг может быть выполнен на произвольное число разрядов от 0 до 255. В процессорах, начиная с 80286, в качестве счётчика сдвига используются только младшие 5 разрядов регистра CL, что ограничивает максимальное количество сдвигов (не более 31).


Микропроцессоры 8086 и 8088 не маскируют значение счётчика сдвига. Таким образом, сдвиг может быть выполнен на произвольное число разрядов от 0 до 255. В процессорах, начиная с 80286, в качестве счётчика сдвига используются только младшие 5 разрядов регистра CL, что ограничивает максимальное количество сдвигов (не более 31).


Команда SBB используется при вычитании двоичных чисел с разрядностью, превышающей 16. В этом случае вычитание младших частей операндов выполняется с помощью инструкции SUB, а последующих частей операндов – с помощью инструкций SBB, следующих за SUB.
Совместно с командами десятичной коррекции сложения AAS
и DAS
инструкции SUB
и SBB
обеспечивают вычитание двоично-десятичных распакованных и упакованных чисел.


При записи на языке ассемблера либо используется мнемоника SCASB
или SCASW, явно определяющая размер операндов, либо используется обобщённая мнемоника SCAS
с указанием местоположения операнда в памяти. Следует, однако, помнить, что адресация операнда в памяти всегда осуществляется с помощью регистровой пары ES:DI, поэтому указанный в данной инструкции адрес используется только для определения размера операнда и, возможно, для применения префикса замены сегмента. За правильность установки начальных значений регистров отвечает программист.


Микропроцессоры 8086 и 8088 не маскируют значение счётчика сдвига. Таким образом, сдвиг может быть выполнен на произвольное число разрядов от 0 до 255. В процессорах, начиная с 80286, в качестве счётчика сдвига используются только младшие 5 разрядов регистра CL, что ограничивает максимальное количество сдвигов (не более 31).


Микропроцессоры 8086 и 8088 не маскируют значение счётчика сдвига. Таким образом, сдвиг может быть выполнен на произвольное число разрядов от 0 до 255. В процессорах, начиная с 80286, в качестве счётчика сдвига используются только младшие 5 разрядов регистра CL, что ограничивает максимальное количество сдвигов (не более 31).


При записи на языке ассемблера либо используется мнемоника STOSB
или STOSW, явно определяющая размер операндов, либо используется обобщённая мнемоника STOS
с указанием местоположения операнда в памяти. Следует, однако, помнить, что адресация операнда в памяти всегда осуществляется с помощью регистровой пары ES:DI, поэтому указанный в данной инструкции адрес используется только для определения размера операнда и, возможно, для применения префикса замены сегмента. За правильность установки начальных значений регистров отвечает программист.


Команда SUB используется при вычитании двоичных чисел с разрядностью 8 или 16. Если требуется выполнить вычитание более длинных чисел, младшие их части вычитаются с помощью инструкции SUB, а остальные – с помощью инструкции SBB.
Совместно с командами десятичной коррекции сложения AAS
и DAS
инструкции SUB
и SBB
обеспечивают вычитание двоично-десятичных распакованных и упакованных чисел.


Архитектура микропроцессоров 8086/8088 позволяет подключить к ним сопроцессор любого назначения, выполняющий те или иные дополнительные команды и, естественно, согласующий свою работу на уровне аппаратуры с основным процессором. Коды этих команд содержат в старших пяти разрядах первого байта комбинацию 11011; для основного процессора это команда ESC. Исторически сложилось, что единственным используемым сопроцессором стал арифметический сопроцессор 8087, содержащий мощную собственную систему команд. Её описание не входит в задачу данной публикации.

Содержание раздела