Непосредственные операнды
Непосредственный операнд – это константа, задаваемая кодом команды. Он может иметь длину 1 или 2 байта в зависимости от разрядности выполняемой операции. Естественно, непосредственный операнд может быть только источником, но не приёмником результата.
Если приёмником в инструкции, использующей непосредственный операнд, является ячейка памяти, а не регистр общего назначения, может потребоваться использование указания BYTE PTR
или WORD PTR. Оно применяется в том случае, когда транслятор с языка ассемблера не может самостоятельно правильно определить разрядность операции. Например, в следующем примере первая команда обнулит байт памяти по смещению 1000h, а вторая – слово по тому же адресу (т.е. байты со смещениями 1000h и 1001h):
MOV BYTE PTR 1000h, 0
MOV WORD PTR 1000h, 0
Непосредственный операнд
8- или 16-разрядный непосредственный операнд присутствует только в командах вида “регистр–непосредственный операнд” и “память–непосредственный операнд”. Его наличие определяется кодом операции, который состоит из байта кода операции и поля Reg байта ModRegR/M. Поля Mod и R/M этого байта определяют местоположение второго операнда инструкции – в регистре общего назначения или в памяти.
Непосредственный операнд располагается в коде команды непосредственно за отклонением, а если последнее отсутствует – за байтом ModRegR/M. Байты 16-разрядного непосредственного операнда хранятся в порядке “младший–старший”.
В инструкциях, обрабатывающих байты, непосредственный операнд всегда имеет размер один байт. В инструкциях, обрабатывающих слова, непосредственный операнд может занимать один или два байта, при этом байтовый операнд, рассматриваемый как двоичное число со знаком, расширяется до слова.
NOP – нет операции
90 | NOP |
| нет операции |
Описание.
Никаких действий не производится.
Флажки не изменяются.
NOT – инверсия
F6 /2 | NOT r/m8 | r/m8:= NOT r/m8 | |||
F7 /2 | NOT r/m16 | r/m16:= NOT r/m16 |
Описание.
Производится инверсия операнда.
Флажки не изменяются.
Общие сведения
Процессор 8086 стал первым 16-разрядным микропроцессором, разработанным фирмой Intel. Он был выпущен в 1978 году и содержал 29 тыс. транзисторов (для сравнения: в первых Pentium’ах число транзисторов превышало 3 млн.). Почти одновременно был выпущен микропроцессор 8088. С точки зрения программиста, эти микропроцессоры абсолютно идентичны, однако микропроцессор 8086 имел 16-разрядную шину данных, а 8088 – 8-разрядную. Благодаря этому обстоятельству микропроцессор 8088 мог легко использоваться совместно с большим количеством разнообразных периферийных микросхем, разработанных к тому времени и ориентированных на работу с 8-разрядными микропроцессорами, в том числе с микропроцессором 8080 фирмы Intel (советский аналог – К580ВМ80). Однако его производительность оказывалась ощутимо меньше, чем у микропроцессора 8086, поскольку в процессе работы ему требовалось практически в два раза больше обращений к памяти.
16-разрядные микропроцессоры фирмы Intel позволяли адресовать до 1 Мбайта памяти, для чего с помощью механизма сегментации формировался 20-разрядный адрес памяти. Адресное пространство ввода-вывода достигало 64 Кбайт (адрес порта занимал 16 разрядов). Для сравнения: 8-разрядный микропроцессор 8080 был способен адресовать 64 Кбайта памяти и 256 портов ввода-вывода.
Процессоры 8086 и 8088 могли работать с максимальной тактовой частотой 8 МГц, обеспечивая быстродействие до 4 млн. операций в секунду. Фирма IBM, взявшись за разработку своего персонального компьютера, для ускорения и удешевления работы воспользовалась микропроцессором 8088, работающим с тактовой частотой всего 4,77 МГц, т.е. почти в два раза меньше предельно допустимой. Поэтому первые персональные компьютеры семейства IBM PC использовали далеко не все возможности, уже тогда предоставляемые микропроцессором.
Специально для работы совместно с микропроцессорами 8086/8088 предназначался математический сопроцессор 8087. Описание принципов его работы не входит в задачу данной книги.
Несколько западных фирм выпустили свои варианты процессоров 8086 и 8088. Некоторые из этих клонов имели расширенную систему команд, однако все они были совместимы “снизу вверх” с изделиями фирмы Intel. В СССР был выпущен микропроцессорный комплект К1810, в который входили микропроцессоры К1810ВМ86 и К1810ВМ88, полностью совпадающие со своими американскими прототипами, а также другие микросхемы, обеспечивающие работу процессоров в составе вычислительной системы и также являющиеся копиями аналогичных изделий фирмы Intel.
Поскольку, с точки зрения программиста, микропроцессоры 8086 и 8088 идентичны, в дальнейшем для простоты будет говориться только о микропроцессоре 8086, хотя всё сказанное, если не указывается противное, в равной мере относится и к микропроцессору 8088. Аналоги, выпускавшиеся другими фирмами, упоминаться не будут, поскольку всё, что было реализовано в изделиях фирмы Intel, имелось и в их клонах.
Операнды в памяти
Как уже отмечалось в подразделе 2.2.2 “Сегментация”, адрес памяти складывается из селектора сегмента и смещения. Смещение операнда в соответствующем сегменте называется эффективным адресом и вычисляется в процессе выполнения инструкции.
Для определения физического адреса явно заданного операнда, располагающегося в памяти, почти во всех случаях используется селектор сегмента, содержащийся в регистре сегмента данных DS. Исключением является лишь случай обращения к операнду, при вычислении эффективного адреса (смещения) которого используется содержимое регистра BP. В этом случае предполагается, что операнд располагается в сегменте стека, и используется селектор сегмента, хранящийся в регистре SS. В любом случае возможно использование префикса замены сегмента, явным образом определяющего, какой сегментный регистр содержит селектор, который должен использоваться при формировании физического адреса. На языке ассемблера префикс замены сегмента указывается с помощью мнемоники соответствующего сегментного регистра, предшествующей эффективному адресу операнда и отделяемой от него двоеточием. Например, в первой из следующих инструкций обращение осуществляется к сегменту данных, поскольку префикс замены сегмента не используется, а регистр BP в формировании эффективного адреса не участвует; во второй инструкции операнд находится в сегменте кода, поскольку сегмент задан явно. Эффективный адрес в обоих случаях является суммой содержимого регистра BX и константы 10h (называемой отклонением):
MOV 10h [BX], AX
MOV CS:10h [BX], AX
Эффективный адрес формируется суммированием содержимого одного или двух регистров общего назначения и 8- или 16-разрядного отклонения (константы, задаваемой кодом команды). Эффективный адрес всегда имеет размер 16 бит; перенос из старшего разряда, если он возникает, игнорируется.
Первым из регистров, участвующих в формировании эффективного адреса, может быть регистр BX или BP, вторым – SI или DI. Другие регистры общего назначения в формировании эффективного адреса применяться не могут.
С любым из регистров или их комбинаций может использоваться 8- или 16-разрядное отклонение; отклонение может также отсутствовать. Исключением является случай использования регистра BP без регистра SI или DI: в такой ситуации всегда должно применяться 8- или 16-разрядное отклонение. Кроме того, эффективный адрес может быть задан 16-разрядным отклонением без использования каких-либо регистров.
На языке ассемблера регистр, участвующий в формировании эффективного адреса, заключается в квадратные скобки. Если применяются два регистра, то либо каждый из них заключается в свои собственные скобки, либо они находятся внутри одних скобок и соединяются там знаком “+”. Например, запись [BX][SI]
эквивалентна записи [BX+SI] и означает, что эффективный адрес является суммой содержимого регистров BX и SI.
Если эффективный адрес состоит из одного отклонения и это отклонение задаётся в числовом виде, а не как метка, перед ним обязательно должно стоять указание WORD PTR или BYTE PTR
в зависимости от того, имеет ли этот операнд размер слово или байт. Это требование связано с тем, что числовая величина будет воспринята транслятором языка ассемблера не как отклонение, а как непосредственный операнд (см. следующий подраздел). Таким образом, для занесения содержимого регистра BH в ячейку памяти со смещением 100h в сегменте данных необходимо использовать следующую инструкцию:
MOV BYTE PTR 100h, BH
Если адресуемая ячейка памяти находится не в сегменте данных, указание BYTE PTR
или WORD PTR
не требуется, поскольку перед отклонением будет указан префикс замены сегмента, например:
MOV ES:100h, BH
В инструкции только один из операндов может располагаться в памяти. Вторым операндом обязательно должен быть либо регистровый, либо непосредственный операнд.
Способ формирования эффективного адреса определяется байтом ModRegR/M кода команды. Формат этого байта и назначение его полей будет описано ниже, в подразделе 2.4.2 “Формат кода команды”. Здесь отметим, что двухразрядное поле MOD определяет наличие и размер отклонения, а трёхразрядное поле R/M – используемую комбинацию регистров.Поле Reg в формировании эффективного адреса не участвует.
OR – логическое ИЛИ
08 /r | OR r/m8, r8 | r/m8:= r/m8
OR r8 | |||
09 /r | OR r/m16, r16 | r/m16:= r/m16 OR r16 | |||
0A /r | OR r8, r/m8 | r8:= r8 OR r/m8 | |||
0B /r | OR r16, r/m16 | r16:= r16 OR r/m16 | |||
0C ib | OR AL, imm8 | AL:= AL OR imm8 | |||
0D iw | OR AX, imm16 | AX:= AX OR imm16 | |||
80 /1 ib | OR r/m8, imm8 | r/m8:= r/m8 OR imm8 | |||
81 /1 iw | OR r/m16, imm16 | r/m16:= r/m16 OR imm16 |
Описание.
Выполняется операция “логическое ИЛИ” между операндами инструкции, результат заносится на место первого операнда.
Флажки OF и CF очищаются.
Флажки SF, ZF и PF устанавливаются в соответствии с результатом.
Состояние флажка AF не определено.
Отклонение
Отклонение является 8- или 16-разрядной величиной, используемой при вычислении эффективного адреса операнда. Один или два байта отклонения располагаются в коде команды сразу за байтом ModRegR/M; для 16-разрядного отклонения сначала идёт младший байт, а затем – старший. Наличие отклонения определяется содержимым байта ModRegR/M.
16-разрядное отклонение присутствует в двух случаях: когда поле Mod байта ModRegR/M содержит значение 10 либо когда поле Mod содержит значение 00, а поле R/M – значение 110.
8-разрядное отклонение присутствует, когда поле Mod содержит значение 01.
OUT – вывод информации из порта ввода-вывода
E6
ib | OUT AL, imm8 | вывод из AL в порт imm8 | |||
E7
ib | OUT AX, imm8 | вывод из AX в порт imm8 | |||
EE | OUT AL, DX | вывод из AL в порт [DX] | |||
EF | OUT AX, DX | вывод из AX в порт [DX] |
Описание.
Эта инструкция выводит байт или слово данных из аккумулятора в указанный порт ввода-вывода.
Если информация выводится в порт с адресом в диапазоне 0–FF16, номер порта может быть задан либо в самой команде, либо предварительно загружен в регистр DX. Для вывода информации в порты с номерами, превышающими FF16, может использоваться только косвенная адресация, когда номер порта предварительно загружен в регистр DX.
Флажки не изменяются.
POP – извлечение информации из стека
8F /0 | POP m16 | занесение данных из стека в m16 | |||
58+rw | POP r16 | занесение данных из стека в r16 | |||
1F | POP DS | занесение данных из стека в DS | |||
07 | POP ES | занесение данных из стека в ES | |||
17 | POP SS | занесение данных из стека в SS |
Описание.
Эти инструкции извлекают из стека слово данных и заносят его в указанный операнд.
Слово извлекается из вершины стека, адрес которой находится в регистровой паре SS:SP. После извлечения слова содержимое SP увеличивается на 2.
Флажки не изменяются.
POPF – загрузка регистра флагов из стека
9D | POPF | загрузка слова из вершины стека в регистр FLAGS |
Описание.
Эта инструкция извлекает из стека слово данных и заносит его в регистр FLAGS.
Слово извлекается из вершины стека, адрес которой находится в регистровой паре SS:SP. После извлечения слова содержимое SP увеличивается на 2.
Зарезервированные разряды регистра FLAGS не изменяются.
Флажки загружаются из стека.
Представление информации
Процессор 8086 оперирует 8- и 16-разрядными двоичными числами со знаком и без знака и строками символов длиной от 1 до 65536 символов. Кроме того, имеются команды десятичной коррекции, облегчающие обработку двоично-десятичных чисел.
Префиксы
Префиксы модифицируют выполнение основной команды. Код каждого префикса занимает один байт.
Микропроцессор 8086 имеет 7 префиксов, делящихся на три группы. В коде одной команды могут присутствовать до трёх префиксов, обязательно относящихся к разным группам. Реакция микропроцессора на использование в команде нескольких префиксов из одной группы непредсказуема.
В первую группу входит единственный префикс блокировки шины LOCK
(шестнадцатеричный код префикса F0). Когда он присутствует в команде, на всё время выполнения инструкции системная шина захватывается данным микропроцессором, блокируя запросы к ней со стороны других процессоров многопроцессорной системы.
Во вторую группу входят префиксы повторения операции REP/REPE/REPZ
(F3) и REPNE/REPNZ (F2). Хотя для этой группы предусмотрено пять мнемоник, реально задействовано два кода префиксов. Они используются совместно со строковыми операциями с целью обработки нескольких байтов или слов одной командой.
Префиксы блокировки шины и повторения в программе на языке ассемблера располагаются непосредственно перед мнемоникой основной команды, совместно с которой они используются, например: LOCK OR [BX], AL.
К третьей группе относятся четыре префикса замены сегмента, имеющих следующие коды: 26 – сегмент ES, 2E – сегмент CS, 36 – сегмент SS, 3E – сегмент DS. В отличие от префиксов двух других групп, префиксы замены сегмента на языке ассемблера указываются уже после мнемоники основной команды и входят в состав операнда в памяти, сегмент которого они явно указывают, например: MOV ES:[BX], CX.
Некоторые сложности при программировании на языке ассемблера могут возникнуть при необходимости использовать префикс замены сегмента совместно со строковой операцией. Операнды строковых команд располагаются в сегментах DS и ES, причём заменить на другой можно только сегмент DS. Проблема заключается в том, что строковые инструкции не имеют явно задаваемых операндов, поэтому некуда включить префикс замены сегмента. Некоторые трансляторы с языка ассемблера, например MASM фирмы Microsoft и TASM фирмы Borland позволяют совместно с мнемоникой строковой операции указать формальные операнды, проверяемые синтаксически, но не играющие никакой роли при формировании кода операции. В этих операндах может быть указан и префикс замены сегмента. В некоторых случаях, однако, приходится вносить в программу непосредственно код префикса замены сегмента, предшествующий соответствующей строковой инструкции. Например, следующие две строки на языке ассемблера задают выполнение операции пересылки строк MOVSB с использованием префикса повторения REP
и префикса замены сегмента CS:
DB 2Eh
REP MOVSB
Прерывание по ошибке деления
Прерывание по ошибке деления возникает при выполнении инструкции DIV
или IDIV, если результат прерывает максимально допустимую величину, а также при попытке деления на нуль.
Выполнение инструкции деления прекращается, управление передаётся обработчику прерывания по вектору 0. В стеке будет сохранён адрес инструкции деления, вызвавшей прерывание.
Прерывание по переполнению
Прерывание по переполнению происходит, если при выполнении инструкции INTO
флажок переполнения OF в регистре флагов установлен. Когда этот флажок сброшен, инструкция INTO никаких действий не производит. Обработчик прерывания по переполнению использует вектор 4.
При прерывании в стеке сохраняется адрес следующей инструкции.
Прерывание по точке останова
Прерывание по точке останова возникает, если в программе встретилась инструкция INT3. Выполнение этой инструкции приводит к передаче управления обработчику прерывания по вектору 3. В стеке сохраняется адрес следующей инструкции.
Следует обратить внимание, что система команд микропроцессора 8086 обеспечивает два формата инструкции INT3 – однобайтовый (код команды CC) и двухбайтовый (код команды CD 03). Функционально они ничем не отличаются, но двухбайтовый формат принято относить к программным прерываниям, а однобайтовый – к исключениям.
Прерывание по трассировке
Прерывания по трассировке происходят после выполнения каждой инструкции, когда в регистре флагов установлен флажок трассировки TF. В этом случае, завершив выполнение инструкции, микропроцессор передаёт управление обработчик прерывания по вектору 1. В стеке сохраняется адрес следующей инструкции.
Особенностью микропроцессоров семейства 8086 является то, что впервые после установки флажка трассировки связанное с ним прерывание происходит не после инструкции, в ходе выполнения которой этот флажок был установлен, а по завершении следующей за ней инструкции. Например, если при завершении обработчика прерывания по трассировке с помощью команды IRET
в восстановленном содержимом регистра флагов флажок TF окажется установлен, то новое прерывание по трассировке произойдёт не сразу после выполнения инструкции IRET, а по завершении команды, на которую инструкцией IRET будет возвращено управление. В процессорах других ЭВМ, не обеспечивающих подобной задержки прерывания по трассировке, обычно используются две инструкции возврата из прерывания – одна для “обычного” возврата, другая – для возврата с задержкой прерывания по трассировке. Например, в 16-разрядных мини-ЭВМ семейства PDP-11 фирмы DEC (советский аналог – ЭВМ типа СМ-3, СМ-4, СМ-1420 и т.п.) имеются инструкции возврата из прерывания RTI
и RTT, отличающиеся друг от друга именно реакцией на флажок трассировки.
Коды операций
Код команды | Команда | ||||||||
1-й байт | 2-й байт | 3–6-й байты | |||||||
Шестн. | Двоичный | ||||||||
00 | 00000000 | ModRegR/M | [disp8/16] | ADD r/m8, r8 | |||||
01 | 00000001 | ModRegR/M | [disp8/16] | ADD r/m16, r16 | |||||
02 | 00000010 | ModRegR/M | [disp8/16] | ADD r8, r/m8 | |||||
03 | 00000011 | ModRegR/M | [disp8/16] | ADD r16, r/m16 | |||||
04 | 00000100 | imm8 | ADD AL, imm8 | ||||||
05 | 00000101 | imm16 | ADD AX, imm16 | ||||||
06 | 00000110 | PUSH ES | |||||||
07 | 00000111 | POP ES | |||||||
08 | 00001000 | ModRegR/M | [disp8/16] | OR r/m8, r8 | |||||
09 | 00001001 | ModRegR/M | [disp8/16] | OR r/m16, r16 | |||||
0A | 00001010 | ModRegR/M | [disp8/16] | OR r8, r/m8 | |||||
0B | 00001011 | ModRegR/M | [disp8/16] | OR r16, r/m16 | |||||
0C | 00001100 | imm8 | OR AL, imm8 | ||||||
0D | 00001101 | imm16 | OR AX, imm16 | ||||||
0E | 00001110 | PUSH CS | |||||||
0F | 00001111 | не используется | |||||||
10 | 00010000 | ModRegR/M | [disp8/16] | ADC r/m8, r8 | |||||
11 | 00010001 | ModRegR/M | [disp8/16] | ADC r/m16, r16 | |||||
12 | 00010010 | ModRegR/M | [disp8/16] | ADC r8, r/m8 | |||||
13 | 00010011 | ModRegR/M | [disp8/16] | ADC r16, r/m16 | |||||
14 | 00010100 | imm8 | ADC AL, imm8 | ||||||
15 | 00010101 | imm16 | ADC AX, imm16 | ||||||
16 | 00010110 | PUSH SS | |||||||
17 | 00010111 | POP SS | |||||||
18 | 00011000 | ModRegR/M | [disp8/16] | SBB r/m8, r8 | |||||
19 | 00011001 | ModRegR/M | [disp8/16] | SBB r/m16, r16 | |||||
1A | 00011010 | ModRegR/M | [disp8/16] | SBB r8, r/m8 | |||||
1B | 00011011 | ModRegR/M | [disp8/16] | SBB r16, r/m16 | |||||
1C | 00011100 | imm8 | SBB AL, imm8 | ||||||
1D | 00011101 | imm16 | SBB AX, imm16 | ||||||
1E | 00011110 | PUSH DS | |||||||
1F | 00011111 | POP DS | |||||||
20 | 00100000 | ModRegR/M | [disp8/16] | AND r/m8, r8 | |||||
21 | 00100001 | ModRegR/M | [disp8/16] | AND r/m16, r16 | |||||
22 | 00100010 | ModRegR/M | [disp8/16] | AND r8, r/m8 | |||||
23 | 00100011 | ModRegR/M | [disp8/16] | AND r16, r/m16 | |||||
24 | 00100100 | imm8 | AND AL, imm8 | ||||||
25 | 00100101 | imm16 | AND AX, imm16 | ||||||
26 | 00100110 | ES: | |||||||
27 | 00100111 | DAA | |||||||
28 | 00101000 | ModRegR/M | [disp8/16] | SUB r/m8, r8 | |||||
29 | 00101001 | ModRegR/M | [disp8/16] | SUB r/m16, r16 | |||||
2A | 00101010 | ModRegR/M | [disp8/16] | SUB r8, r/m8 | |||||
2B | 00101011 | ModRegR/M | [disp8/16] | SUB r16, r/m16 | |||||
2C | 00101100 | imm8 | SUB AL, imm8 | ||||||
2D | 00101101 | imm16 | SUB AX, imm16 | ||||||
2E | 00101110 | CS: | |||||||
2F | 00101111 | DAS | |||||||
30 | 00110000 | ModRegR/M | [disp8/16] | XOR r/m8, r8 | |||||
31 | 00110001 | ModRegR/M | [disp8/16] | XOR r/m16, r16 | |||||
32 | 00110010 | ModRegR/M | [disp8/16] | XOR r8, r/m8 | |||||
33 | 00110011 | ModRegR/M | [disp8/16] | XOR r16, r/m16 | |||||
34 | 00110100 | imm8 | XOR AL, imm8 | ||||||
35 | 00110101 | imm16 | XOR AX, imm16 | ||||||
36 | 00110110 | SS: | |||||||
37 | 00110111 | AAA | |||||||
38 | 00111000 | ModRegR/M | [disp8/16] | CMP r/m8, r8 | |||||
39 | 00111001 | ModRegR/M | [disp8/16] | CMP r/m16, r16 | |||||
3A | 00111010 | ModRegR/M | [disp8/16] | CMP r8, r/m8 | |||||
3B | 00111011 | ModRegR/M | [disp8/16] | CMP r16, r/m16 | |||||
3C | 00111100 | imm8 | CMP AL, imm8 | ||||||
3D | 00111101 | imm16 | CMP AX, imm16 | ||||||
3E | 00111110 | SS: | |||||||
3F | 00111111 | AAS | |||||||
40 | 01000000 | INC AX | |||||||
41 | 01000001 | INC CX | |||||||
42 | 01000010 | INC DX | |||||||
43 | 01000011 | INC BX | |||||||
44 | 01000100 | INC SP | |||||||
45 | 01000101 | INC BP | |||||||
46 | 01000110 | INC SI | |||||||
47 | 01000111 | INC DI | |||||||
48 | 01001000 | DEC AX | |||||||
49 | 01001001 | DEC CX | |||||||
4A | 01001010 | DEC DX | |||||||
4B | 01001011 | DEC BX | |||||||
4C | 01001100 | DEC SP | |||||||
4D | 01001101 | DEC BP | |||||||
4E | 01001110 | DEC SI | |||||||
4F | 01001111 | DEC DI | |||||||
50 | 01010000 | PUSH AX | |||||||
51 | 01010001 | PUSH CX | |||||||
52 | 01010010 | PUSH DX | |||||||
53 | 01010011 | PUSH BX | |||||||
54 | 01010100 | PUSH SP | |||||||
55 | 01010101 | PUSH BP | |||||||
56 | 01010110 | PUSH SI | |||||||
57 | 01010111 | PUSH DI | |||||||
58 | 01011000 | POP AX | |||||||
59 | 01011001 | POP CX | |||||||
5A | 01011010 | POP DX | |||||||
5B | 01011011 | POP BX | |||||||
5C | 01011100 | POP SP | |||||||
5D | 01011101 | POP BP | |||||||
5E | 01011110 | POP SI | |||||||
5F | 01011111 | POP DI | |||||||
60
/ 6F | 01100000
/ 01101111 | не используются | |||||||
70 | 01110000 | rel8 | JO rel8 | ||||||
71 | 01110001 | rel8 | JNO rel8 | ||||||
72 | 01110010 | rel8 | JB rel8
JNAE rel8 JC rel8 | ||||||
73 | 01110011 | rel8 | JNB rel8
JAE rel8 JNC rel8 | ||||||
74 | 01110100 | rel8 | JE rel8
JZ rel8 | ||||||
75 | 01110101 | rel8 | JNE rel8
JNZ rel8 | ||||||
76 | 01110110 | rel8 | JBE rel8
JNA rel8 | ||||||
77 | 01110111 | rel8 | JNBE rel8
JA rel8 | ||||||
78 | 01111000 | rel8 | JS rel8 | ||||||
79 | 01111001 | rel8 | JNS rel8 | ||||||
7A | 01111010 | rel8 | JP rel8
JPE rel8 | ||||||
7B | 01111011 | rel8 | JNP rel8
JPO rel8 | ||||||
7C | 01111100 | rel8 | JL rel8
JNGE rel8 | ||||||
7D | 01111101 | rel8 | JNL rel8
JGE rel8 | ||||||
7E | 01111110 | rel8 | JLE rel8
JNG rel8 | ||||||
7F | 01111111 | rel8 | JNLE rel8
JG rel8 | ||||||
80 | 10000000 | Mod000R/M | [disp8/16] imm8 | ADD r/m8, imm8 | |||||
Mod001R/M | [disp8/16] imm8 | OR r/m8, imm8 | |||||||
Mod010R/M | [disp8/16] imm8 | ADC r/m8, imm8 | |||||||
Mod011R/M | [disp8/16] imm8 | SBB r/m8, imm8 | |||||||
Mod100R/M | [disp8/16] imm8 | AND r/m8, imm8 | |||||||
Mod101R/M | [disp8/16] imm8 | SUB r/m8, imm8 | |||||||
Mod110R/M | [disp8/16] imm8 | XOR r/m8, imm8 | |||||||
Mod111R/M | [disp8/16] imm8 | CMP r/m8, imm8 | |||||||
81 | 10000001 | Mod000R/M | [disp8/16] imm8 | ADD r/m16, imm16 | |||||
Mod001R/M | [disp8/16] imm8 | OR r/m16, imm16 | |||||||
Mod010R/M | [disp8/16] imm8 | ADC r/m16, imm16 | |||||||
Mod011R/M | [disp8/16] imm8 | SBB r/m16, imm16 | |||||||
Mod100R/M | [disp8/16] imm8 | AND r/m16, imm16 | |||||||
Mod101R/M | [disp8/16] imm8 | SUB r/m16, imm16 | |||||||
Mod110R/M | [disp8/16] imm8 | XOR r/m16, imm16 | |||||||
Mod111R/M | [disp8/16] imm8 | CMP r/m16, imm16 | |||||||
82 | 10000010 | не используется | |||||||
83 | 10000011 | Mod000R/M | [disp8/16] imm8 | ADD r/m16, imm8 | |||||
xx001xxx | не используется | ||||||||
Mod010R/M | [disp8/16] imm8 | ADC r/m16, imm8 | |||||||
Mod011R/M | [disp8/16] imm8 | SBB r/m16, imm8 | |||||||
xx100xxx | не используется | ||||||||
Mod101R/M | [disp8/16] imm8 | SUB r/m16, imm8 | |||||||
xx110xxx | не используется | ||||||||
xx111xxx | не используется | ||||||||
84 | 10000100 | ModRegR/M | [disp8/16] | TEST r/m8, r8 | |||||
85 | 10000101 | ModRegR/M | [disp8/16] | TEST r/m16, r16 | |||||
86 | 10000110 | ModRegR/M | [disp8/16] | XCHG r/m8, r8 | |||||
87 | 10000111 | ModRegR/M | [disp8/16] | XCHG r/m16, r16 | |||||
88 | 10001000 | ModRegR/M | [disp8/16] | MOV r/m8, r8 | |||||
89 | 10001001 | ModRegR/M | [disp8/16] | MOV r/m16, r16 | |||||
8A | 10001010 | ModRegR/M | [disp8/16] | MOV r8, r/m8 | |||||
8B | 10001011 | ModRegR/M | [disp8/16] | MOV r16, r/m16 | |||||
8C | 10001100 | Mod0SRR/M | [disp8/16] | MOV r/m16, Sreg | |||||
xx1xxxxx | не используется | ||||||||
8D | 10001101 | ModRegR/M | [disp8/16] | LEA r16, m | |||||
8E | 10001110 | Mod0SRR/M | [disp8/16] | MOV r/m16, Sreg | |||||
xx1xxxxx | не используется | ||||||||
8F | 10001111 | Mod000R/M | [disp8/16] | POP r/m16 | |||||
xx001xxx
/ xx111xxx | не используется | ||||||||
90 | 10010000 | NOP (XCHG AX, AX) | |||||||
91 | 10010001 | XCHG AX, CX | |||||||
92 | 10010010 | XCHG AX, DX | |||||||
93 | 10010011 | XCHG AX, BX | |||||||
94 | 10010100 | XCHG AX, SP | |||||||
95 | 10010101 | XCHG AX, BP | |||||||
96 | 10010110 | XCHG AX, SI | |||||||
97 | 10010111 | XCHG AX, DI | |||||||
98 | 10011000 | CBW | |||||||
99 | 10011001 | CWD | |||||||
9A | 10011010 | ptr16:16 | CALL ptr16:16 | ||||||
9B | 10011011 | WAIT | |||||||
9C | 10011100 | PUSHF | |||||||
9D | 10011101 | POPF | |||||||
9E | 10011110 | SAHF | |||||||
9F | 10011111 | LAHF | |||||||
A0 | 10100000 | m8 | MOV AL, m8 | ||||||
A1 | 10100001 | m16 | MOV AX, m16 | ||||||
A2 | 10100010 | m8 | MOV m8, AL | ||||||
A3 | 10100011 | m16 | MOV m16, AX | ||||||
A4 | 10100100 | MOVSB | |||||||
A5 | 10100101 | MOVSW | |||||||
A6 | 10100110 | CMPSB | |||||||
A7 | 10100111 | CMPSW | |||||||
A8 | 10101000 | imm8 | TEST AL, imm8 | ||||||
A9 | 10101001 | imm16 | TEST AX, imm16 | ||||||
AA | 10101010 | STOSB | |||||||
AB | 10101011 | STOSW | |||||||
AC | 10101100 | LODSB | |||||||
AD | 10101101 | LODSW | |||||||
AE | 10101110 | SCASB | |||||||
AF | 10101111 | SCASW | |||||||
B0 | 10110000 | imm8 | MOV AL, imm8 | ||||||
B1 | 10110001 | imm8 | MOV CL, imm8 | ||||||
B2 | 10110010 | imm8 | MOV DL, imm8 | ||||||
B3 | 10110011 | imm8 | MOV BL, imm8 | ||||||
B4 | 10110100 | imm8 | MOV AH, imm8 | ||||||
B5 | 10110101 | imm8 | MOV CH, imm8 | ||||||
B6 | 10110110 | imm8 | MOV DH, imm8 | ||||||
B7 | 10110111 | imm8 | MOV BH, imm8 | ||||||
B8 | 10111000 | imm16 | MOV AX, imm16 | ||||||
B9 | 10111001 | imm16 | MOV CX, imm16 | ||||||
BA | 10111010 | imm16 | MOV DX, imm16 | ||||||
BB | 10111011 | imm16 | MOV BX, imm16 | ||||||
BC | 10111100 | imm16 | MOV SP, imm16 | ||||||
BD | 10111101 | imm16 | MOV BP, imm16 | ||||||
BE | 10111110 | imm16 | MOV SI, imm16 | ||||||
BF | 10111111 | imm16 | MOV DI, imm16 | ||||||
C0 | 11000000 | не используется | |||||||
C1 | 11000001 | не используется | |||||||
C2 | 11000010 | imm16 | RET imm16 (ближний) | ||||||
C3 | 11000011 | RET
(ближний) | |||||||
C4 | 11000100 | ModRegR/M | [disp8/16] | LES r16, m16:16 | |||||
C5 | 11000101 | ModRegR/M | [disp8/16] | LDS r16, m16:16 | |||||
C6 | 11000110 | Mod000R/M | [disp8/16] imm8 | MOV m8, imm8 | |||||
xx001xxx
/ xx111xxx | не используется | ||||||||
C7 | 11000111 | Mod000R/M | [disp8/16] imm16 | MOV m16, imm16 | |||||
xx001xxx
/ xx111xxx | не используется | ||||||||
C8 | 11001000 | не используется | |||||||
C9 | 11001001 | не используется | |||||||
CA | 11001010 | imm16 | RET imm16 (дальний) | ||||||
CB | 11001011 | RET (дальний) | |||||||
CC | 11001100 | INT 3 | |||||||
CD | 11001101 | imm8 | INT imm8 | ||||||
CE | 11001110 | INTO | |||||||
CF | 11001111 | IRET | |||||||
D0 | 11010000 | Mod000R/M | [disp8/16] | ROL r/m8, 1 | |||||
Mod001R/M | [disp8/16] | ROR r/m8, 1 | |||||||
Mod010R/M | [disp8/16] | RCL r/m8, 1 | |||||||
Mod011R/M | [disp8/16] | RCR r/m8, 1 | |||||||
Mod100R/M | [disp8/16] | SAL r/m8, 1
SHL r/m8, 1 | |||||||
Mod101R/M | [disp8/16] | SHR r/m8, 1 | |||||||
xx110xxx | не используется | ||||||||
Mod111R/M | [disp8/16] | SAR r/m8, 1 | |||||||
D1 | 11010001 | Mod000R/M | [disp8/16] | ROL r/m16, 1 | |||||
Mod001R/M | [disp8/16] | ROR r/m16, 1 | |||||||
Mod010R/M | [disp8/16] | RCL r/m16, 1 | |||||||
Mod011R/M | [disp8/16] | RCR r/m16, 1 | |||||||
Mod100R/M | [disp8/16] | SAL r/m16, 1
SHL r/m16, 1 | |||||||
Mod101R/M | [disp8/16] | SHR r/m16, 1 | |||||||
xx110xxx | не используется | ||||||||
Mod111R/M | [disp8/16] | SAR r/m16, 1 | |||||||
D2 | 11010010 | Mod000R/M | [disp8/16] | ROL r/m8, CL | |||||
Mod001R/M | [disp8/16] | ROR r/m8, CL | |||||||
Mod010R/M | [disp8/16] | RCL r/m8, CL | |||||||
Mod011R/M | [disp8/16] | RCR r/m8, CL | |||||||
Mod100R/M | [disp8/16] | SAL r/m8, CL
SHL r/m8, CL | |||||||
Mod101R/M | [disp8/16] | SHR r/m8, CL | |||||||
xx110xxx | не используется | ||||||||
Mod111R/M | [disp8/16] | SAR r/m8, CL | |||||||
D3 | 11010011 | Mod000R/M | [disp8/16] | ROL r/m16, CL | |||||
Mod001R/M | [disp8/16] | ROR r/m16, CL | |||||||
Mod010R/M | [disp8/16] | RCL r/m16, CL | |||||||
Mod011R/M | [disp8/16] | RCR r/m16, CL | |||||||
Mod100R/M | [disp8/16] | SAL r/m16, CL
SHL r/m16, CL | |||||||
Mod101R/M | [disp8/16] | SHR r/m16, CL | |||||||
xx110xxx | не используется | ||||||||
Mod111R/M | [disp8/16] | SAR r/m16, CL | |||||||
D4 | 11010100 | AAM | |||||||
D5 | 11010101 | AAD | |||||||
D6 | 11010110 | не используется | |||||||
D7 | 11010111 | XLATB | |||||||
D8
/ DF | 11011xxx | ModRegR/M | [disp8/16] | ESC | |||||
E0 | 11100000 | rel8 | LOOPNE rel8
LOOPNZ rel8 | ||||||
E1 | 11100001 | rel8 | LOOPE rel8
LOOPZ rel8 | ||||||
E2 | 11100010 | rel8 | LOOP rel8 | ||||||
E3 | 11100011 | rel8 | JCXZ rel8 | ||||||
E4 | 11100100 | imm8 | IN AL, imm8 | ||||||
E5 | 11100101 | imm8 | IN AX, imm8 | ||||||
E6 | 11100110 | imm8 | OUT AL, imm8 | ||||||
E7 | 11100111 | imm8 | OUT AX, imm8 | ||||||
E8 | 11101000 | rel16 | CALL rel16 | ||||||
E9 | 11101001 | rel16 | JMP rel16 | ||||||
EA | 11101010 | ptr16:16 | JMP ptr16:16 | ||||||
EB | 11101011 | rel8 | JMP rel8 | ||||||
EC | 11101100 | IN AL, DX | |||||||
ED | 11101101 | IN AX, DX | |||||||
EE | 11101110 | OUT AL, DX | |||||||
EF | 11101111 | OUT AX, DX | |||||||
F0 | 11110000 | LOCK | |||||||
F1 | 11110001 | не используется | |||||||
F2 | 11110010 | REPNE
REPNZ | |||||||
F3 | 11110011 | REP
REPE REPZ | |||||||
F4 | 11110100 | HLT | |||||||
F5 | 11110101 | CMC | |||||||
F6 | 11110110 | Mod000R/M | [disp8/16] imm8 | TEST r/m8, imm8 | |||||
xx001xxx | не используется | ||||||||
Mod010R/M | [disp8/16] | NOT r/m8 | |||||||
Mod011R/M | [disp8/16] | NEG r/m8 | |||||||
Mod100R/M | [disp8/16] | MUL r/m8 | |||||||
Mod101R/M | [disp8/16] | IMUL r/m8 | |||||||
Mod110R/M | [disp8/16] | DIV r/m8 | |||||||
Mod111R/M | [disp8/16] | IDIV r/m8 | |||||||
F7 | 11110111 | Mod000R/M | [disp8/16] imm8 | TEST r/m16, imm16 | |||||
xx001xxx | не используется | ||||||||
Mod010R/M | [disp8/16] | NOT r/m16 | |||||||
Mod011R/M | [disp8/16] | NEG r/m16 | |||||||
Mod100R/M | [disp8/16] | MUL r/m16 | |||||||
Mod101R/M | [disp8/16] | IMUL r/m16 | |||||||
Mod110R/M | [disp8/16] | DIV r/m16 | |||||||
Mod111R/M | [disp8/16] | IDIV r/m16 | |||||||
F8 | 11111000 | CLC | |||||||
F9 | 11111001 | STC | |||||||
FA | 11111010 | CLI | |||||||
FB | 11111011 | STI | |||||||
FC | 11111100 | CLD | |||||||
FD | 11111101 | STD | |||||||
FE | 11111110 | Mod000R/M | [disp8/16] | INC r/m8 | |||||
Mod001R/M | [disp8/16] | DEC r/m8 | |||||||
xx010xxx
/ xx111xxx | не используется | ||||||||
FF | 11111111 | Mod000R/M | [disp8/16] | INC r/m16 | |||||
Mod001R/M | [disp8/16] | DEC r/m16 | |||||||
Mod010R/M | [disp8/16] | CALL r/m16 | |||||||
Mod011R/M | [disp8/16] | CALL m16:16 | |||||||
Mod100R/M | [disp8/16] | JMP r/m16 | |||||||
Mod101R/M | [disp8/16] | JMP m16:16 | |||||||
Mod110R/M | [disp8/16] | PUSH r/m16 | |||||||
xx111xxx | не используется |
Время выполнения команд
В этом приложении приведено время выполнения команд и прерываний в машинных тактах для микропроцессора 8086 (КР1810ВМ86). Для микропроцессора 8088 время выполнения многих команд будет больше, поскольку ему требуется больше обращений к памяти.
Во многих командах общее время выполнения складывается из некоторого “базового” количества тактов плюс количества, необходимого для вычисления эффективного адреса.
Время вычисления эффективного адреса | |||||||||||||
Поле R/M | Mod=00 | Mod=01 | Mod=10 | ||||||||||
адресация | такты | адресация | такты | адресация | такты | ||||||||
000 | BX+SI | 7 | BX+SI+disp8 | 11 | BX+SI+disp16 | BX+SI+disp8 | |||||||
001 | BX+DI | 8 | BX+DI+disp8 | 12 | BX+DI+disp16 | BX+DI+disp8 | |||||||
010 | BP+SI | 8 | BP+SI+disp8 | 12 | BP+SI+disp16 | BP+SI+disp8 | |||||||
011 | BP+DI | 7 | BP+DI+disp8 | 11 | BP+DI+disp16 | BP+DI+disp8 | |||||||
100 | SI | 5 | SI+disp8 | 9 | SI+disp16 | SI+disp8 | |||||||
101 | DI | 5 | DI+disp8 | 9 | DI+disp16 | DI+disp8 | |||||||
110 | disp16 | 6 | BP+disp8 | 9 | BP+disp16 | BP+disp8 | |||||||
111 | BX | 5 | BX+disp8 | 9 | BX+disp16 | BX+disp8 |
Время выполнения команд | |||
Команда | Такты | ||
AAA | 4 | ||
AAD | 60 | ||
AAS | 4 | ||
AAM | 83 | ||
ADC r, r | 3 | ||
r, m | 9+EA | ||
m, r | 16+EA | ||
r, imm | 4 | ||
m, imm | 17+EA | ||
ADD r, r | 3 | ||
r, m | 9+EA | ||
m, r | 16+EA | ||
r, imm | 4 | ||
m, imm | 17+EA | ||
AND r, r | 3 | ||
r, m | 9+EA | ||
m, r | 16+EA | ||
r, imm | 4 | ||
m, imm | 17+EA | ||
CALL rel16 | 19 | ||
r16 | 16 | ||
m16 | 21+EA | ||
ptr16:16 | 28 | ||
m16:16 | 37+EA | ||
CBW | 2 | ||
CLC | 2 | ||
CLD | 2 | ||
CLI | 2 | ||
CMC | 2 | ||
CMP r, r | 3 | ||
r, m | 9+EA | ||
m, r | 9+EA | ||
r, imm | 4 | ||
m, imm | 10+EA | ||
CMPS | 22 | ||
REP CMPS | 9+22*N | ||
CWD | 5 | ||
DAA | 4 | ||
DAS | 4 | ||
DEC r16 | 2 | ||
r8 | 3 | ||
m | 15+EA | ||
DIV r8 | 80–90 | ||
r16 | 144–162 | ||
m8 | (86–96)+EA | ||
m16 | (150–168)+EA | ||
ESC op, r | 2 | ||
op, m | 8+EA | ||
HLT | 2 | ||
IDIV r8 | 101–112 | ||
r16 | 165–184 | ||
m8 | (107–118)+EA | ||
m16 | (171–190)+EA | ||
IMUL r8 | 80–98 | ||
r16 | 128–154 | ||
m8 | (86–104)+EA | ||
m16 | (134–160)+EA | ||
IN acc, imm8 | 10 | ||
acc, DX | 8 | ||
INC r16 | 2 | ||
r8 | 3 | ||
m | 15+EA | ||
INT 3 | 51 | ||
imm8 | 52 | ||
INTO | 4/53 | ||
IRET | 24 | ||
Jcc rel8 | 4/16 | ||
JCXZ rel8 | 6/18 | ||
JMP rel8/16 | 15 | ||
r16 | 11 | ||
m16 | 18+EA | ||
ptr16:16 | 15 | ||
m16:16 | 24+EA | ||
LAHF | 4 | ||
LDS r16, m16:16 | 16+EA | ||
LEA r16, m | 2+EA | ||
LES r16, m16:16 | 16+EA | ||
LODS | 12 | ||
LOOP rel8 | 5/17 | ||
LOOPE rel8
LOOPZ rel8 | 6/18 | ||
LOOPNE rel8
LOOPNZ rel8 | 5/19 | ||
MOV m, acc | 10 | ||
acc, m | 10 | ||
sr, r16 | 2 | ||
sr, m16 | 8+EA | ||
r16, sr | 2 | ||
m16, sr | 9+EA | ||
r, r | 2 | ||
r, m | 8+EA | ||
m, r | 9+EA | ||
r, imm | 4 | ||
m, imm | 10+EA | ||
MOVS | 18 | ||
REP MOVS | 9+17*N | ||
MUL r8 | 70–77 | ||
r16 | 118–133 | ||
m8 | (76–83)+EA | ||
m16 | (124–139)+EA | ||
NEG r | 3 | ||
m | 16+EA | ||
NOP | 3 | ||
NOT r | 3 | ||
m | 16+EA | ||
OR r, r | 3 | ||
r, m | 9+EA | ||
m, r | 16+EA | ||
r, imm | 4 | ||
m, imm | 17+EA | ||
OUT acc, imm8 | 10 | ||
acc, DX | 8 | ||
POP r16 | 8 | ||
m16 | 17+EA | ||
sr | 8 | ||
POPF | 8 | ||
PUSH r16 | 11 | ||
m16 | 16+EA | ||
sr | 10 | ||
PUSHF | 10 | ||
сдвиг r, 1 | 2 | ||
m, 1 | 15+EA | ||
r, CL | 8+4*N | ||
m, CL | 20+EA+4*N | ||
RET (ближний) | 8 | ||
imm16 (ближний) | 12 | ||
(дальний) | 17 | ||
imm16 (дальний) | 18 | ||
SAHF | 4 | ||
SBB r, r | 3 | ||
r, m | 9+EA | ||
m, r | 16+EA | ||
r, imm | 4 | ||
m, imm | 17+EA | ||
SCAS | 15 | ||
REP SCAS | 9+15*N | ||
STC | 2 | ||
STD | 2 | ||
STI | 2 | ||
STOS | 11 | ||
REP STOS | 9+10*N | ||
SUB r, r | 3 | ||
r, m | 9+EA | ||
m, r | 16+EA | ||
r, imm | 4 | ||
m, imm | 17+EA | ||
TEST r, r | 3 | ||
r, m | 9+EA | ||
m, r | 9+EA | ||
acc, imm | 4 | ||
r, imm | 5 | ||
m, imm | 11+EA | ||
WAIT | 3+5*N | ||
XCHG AX, r16 | 3 | ||
r16, AX | 3 | ||
r, r | 4 | ||
r, m | 17+EA | ||
m, r | 17+EA | ||
XLAT | 11 | ||
XOR r, r | 3 | ||
r, m | 9+EA | ||
m, r | 16+EA | ||
r, imm | 4 | ||
m, imm | 17+EA | ||
Префиксы команд | |||
LOCK | 2 | ||
REP/REPcc | 2 | ||
замены сегмента | 2 | ||
Прерывания | |||
внешние | 61 | ||
немаскируемые | 50 | ||
трассировки | 50 |
В таблице EA – время вычисления эффективного адреса; N – число повторений операции.
[1]
Позднее, при разработке микропроцессора 80286, инженеры фирмы Intel допустили ошибку, из-за чего этот перенос учитывался. Ошибка не была вовремя замечена, и в персональные компьютеры пришлось вводить дополнительные схемы, позволяющие либо блокировать 20-ю линию адреса (чтобы сохранялась совместимость с процессором 8086), либо разрешать её нормальное функционирование (для использования областей памяти с физическими адресами свыше FFFFF16). Эта ошибка из соображений совместимости повторяется и во всех последующих процессорах.
[2]
Примером может служить многозадачная многопользовательская операционная система реального времени RSX-11, способная эффективно работать на ЭВМ с объёмом памяти 128 Кбайт, обеспечивая при этом истинную многозадачность, защиту памяти и предоставляя пользователю куда более широкий набор функций, чем MS DOS, хотя последняя является однозадачной и при этом намного более требовательна к объёму памяти. Начиная с микропроцессора 80386, фирма Intel значительно улучшила эффективность системы команд, но так и не смогла “подтянуть” её даже до уровня PDP-11, не говоря уже о 32-разрядной супермини-ЭВМ VAX-11.
[3]
Нельзя смешивать короткие и длинные переходы с ближними и дальними, т.е. с внутрисегментными и межсегментными.
[4]
В вычислительных системах других архитектур сегментация памяти не используется, и программист работает с логическими (виртуальными) адресами, состоящими не из двух, а из одного-единственного компонента. В таких вычислительных системах для обозначения величины, используемой при относительной адресации, почти всегда используется термин “смещение”, поскольку для них вызывать путаницы он не может.
[5]
Не следует путать номера векторов прерываний, т.е. местоположение адреса программы-обработчика прерывания в таблице векторов прерываний, с номером аппаратного прерывания, т.е. номером линии запроса прерывания, поступающего контроллеру прерываний (номером IRQ).Соответствие между номерами линий прерываний (IRQ) и номерами векторов задаётся при программировании контроллера прерываний и, вообще говоря, к архитектуре микропроцессора прямого отношения не имеет.
Приоритет прерываний
Одновременно может возникать несколько запросов прерываний. В этом случае микропроцессор обслуживает их в соответствии с их приоритетами. Сначала обслуживается прерывание с высшим приоритетом, затем – с более низким (если в результате обслуживания более приоритетного запроса процессор не оказался замаскирован для менее приоритетного прерывания).
Высший приоритет имеют исключения деления, точки останова и переполнения и программные прерывания. Поскольку они взаимно исключают друг друга (могут произойти при выполнении только определённых инструкций микропроцессора), ситуация, когда необходимо обслужить одновременно несколько прерываний этих видов, возникнуть не может.
Следом по приоритету следует немаскируемое внешнее прерывание. Как уже отмечалось, если такое прерывание произошло, следующее немаскируемое прерывание может быть выполнено только после выполнения команды IRET, при этом не играет роли, обработку какого запроса прерывания данная команда завершает (аппаратура микропроцессора реагирует на сам факт выполнения инструкции IRET).
На третьем месте стоят маскируемые внешние прерывания. Поскольку выполнение прерывания приводит к сбросу флажка IF в регистре флагов, выполнение маскируемого прерывания откладывается до тех пор, пока флажок IF не будет вновь установлен.
Самый низкий приоритет имеет трассировочное прерывание.
Программные прерывания
Программные прерывания возникают при выполнении инструкций INT n, где n
– номер вектора прерывания, которое должно произойти. Коды этих команд состоят из двух байтов: первый содержит код операции (CD), второй – номер вектора прерывания. При прерывании в стеке сохраняется адрес следующей инструкции.
PUSH – занесение информации в стек
FF /6 | PUSH r/m16 | занесение данных в стек из r/m16 | |||
58+rw | PUSH r16 | занесение данных в стек из r16 | |||
06 | PUSH ES | занесение в стек ES | |||
0E | PUSH CS | занесение в стек CS | |||
16 | PUSH SS | занесение в стек SS | |||
1E | PUSH DS | занесение в стек DS |
Описание.
Эти инструкции заносят в стек указанное слово данных.
Содержимое SP уменьшается на два, после чего по полученному адресу производится запись заданного слова данных.
Флажки не изменяются.
PUSHF – запись регистра флагов в стек
9C | PUSHF | запись в стек содержимого регистра FLAGS |
Описание.
Эта инструкция заносит в вершину стека содержимое регистра FLAGS.
Перед записью содержимое SP уменьшается на два. Регистр флагов записывается по полученному адресу.
Зарезервированные разряды регистра FLAGS не изменяются.
Флажки не изменяются.
RCL – циклический сдвиг влево через флажок переноса
D0 /2 | RCL r/m8, 1 | циклический сдвиг r/m8 влево на 1 разряд через CF | |||
D2 /2 | RCL r/m8, CL | циклический сдвиг r/m8 влево на CL разрядов через CF | |||
D1 /2 | RCL r/m16, 1 | циклический сдвиг r/m16 влево на 1 разряд через CF | |||
D3 /2 | RCL r/m16, CL | циклический сдвиг r/m16 влево на CL разрядов через CF |
Описание.
Эта инструкция производит циклический сдвиг содержимого своего операнда влево через флажок переноса на указанное вторым операндом число разрядов.
Сдвиг выполняется по следующей схеме:
------------------------¬
¦ ---¬ ----------¬ ¦
L-+CF¦<----+ операнд ¦<--
L--- L----------
Имеются две разновидности сдвига: одноразрядный и многоразрядный. В последнем случае количество разрядов, на которое производится сдвиг, должно быть предварительно занесено в регистр CL.
Флажок CF содержит значение последнего выдвинутого из операнда разряда.
Значение флажка OF в операции многоразрядного сдвига не определено. В операции одноразрядного сдвига он представляет собой результат операции “исключающее ИЛИ” между значением старшего разряда результата и содержимым флажка CF после выполнения сдвига. Таким образом, единичное значение флажка OF свидетельствует о том, что содержимое старшего разряда результата отличается от его исходного значения, а нулевое значение – что старший разряд операнда не изменился.
Флажки SF, ZF, AF и PF не изменяются.
RCR – циклический сдвиг вправо через флажок переноса
D0 /3 | RCR r/m8, 1 | циклический сдвиг r/m8 вправо на 1 разряд через CF | |||
D2 /3 | RCR r/m8, CL | циклический сдвиг r/m8 вправо на CL разрядов через CF | |||
D1 /3 | RCR r/m16, 1 | циклический сдвиг r/m16 вправо на 1 разряд через CF | |||
D3 /3 | RCR r/m16, CL | циклический сдвиг r/m16 вправо на CL разрядов через CF |
Описание.
Эта инструкция производит циклический сдвиг содержимого своего операнда вправо через флажок переноса на указанное вторым операндом число разрядов.
Сдвиг выполняется по следующей схеме:
------------------------¬
¦ ---¬ ----------¬ ¦
L->¦CF+---->¦ операнд +--
L--- L----------
Имеются две разновидности сдвига: одноразрядный и многоразрядный. В последнем случае количество разрядов, на которое производится сдвиг, должно быть предварительно занесено в регистр CL.
Флажок CF содержит значение последнего выдвинутого из операнда разряда.
Значение флажка OF в операции многоразрядного сдвига не определено. В операции одноразрядного сдвига он представляет собой результат операции “исключающее ИЛИ” между содержимым двух самых старших разрядов результата. Таким образом, единичное значение флажка OF указывает, что операнд сменил свой знак, а нулевое – что знак остался неизменным.
Флажки SF, ZF, AF и PF не изменяются.
Регистр флагов
В состав микропроцессора входит 16-разрядный регистр флагов, обозначаемый Flags. Он состоит из отдельных разрядов, имеющих самостоятельное значение. Формат регистра Flags и назначение его битов приведено ниже.
----T---T---T---T----T----T----T----T----T----T---T----T---T----T---T----¬
¦ 1 ¦ 1 ¦ 1 ¦ 1 ¦ OF
¦ DF
¦ IF
¦ TF
¦ SF
¦ ZF
¦ 0 ¦ AF
¦ 0 ¦ PF
¦ 1 ¦ CF
¦
L---+---+---+---+----+----+----+----¦----+----+---+----+---+----+---+-----
15 0
Разряды 15-12, 5, 3 и 1 не используются. При записи они должны содержать значения, показанные на приведённом выше рисунке. В последующих микропроцессорах (80286, 80386 и т.д.) часть этих разрядов была задействована для выполнения новых функций.
OF (разряд 11) – флаг переполнения. Он устанавливается в арифметических операциях, свидетельствуя о возникновении переполнения при обработке чисел со знаком.
DF (разряд 10) – флаг направления. Нулевое значение этого флага соответствует обработке строковых операндов в порядке возрастания их адресов, единичное – в порядке убывания.
IF (разряд 9) – флаг разрешения прерывания. Нулевое значение этого флага запрещает обработку маскируемых прерываний, единичное – разрешает.
TF (разряд 8) – флаг трассировки. Когда он установлен, после выполнения каждой инструкции микропроцессора происходит прерывание, используемое обычно в отладочных целях. Когда этот флаг сброшен, прерывание по окончании инструкции не возникает.
SF (разряд 7) – флаг знака. Изменяется большинством арифметико-логических команд. Нулевое значение показывает, что в операции над числами со знаком было получено неотрицательное число, единичное значение – что результатом является отрицательное число. Таким образом, этот флаг повторяет значение старшего (знакового) разряда результата.
ZF (разряд 6) – флаг нуля. Изменяется большинством арифметико-логических команд. Этот флаг сбрасывается в нуль, если результат операции отличен от нуля, и устанавливается, если результат равен нулю.
AF (разряд 4) – флаг вспомогательного переноса. Устанавливается в командах сложения и вычитания при возникновении переноса из третьего или заёма в третий разряд соответственно. Этот флаг используется командами десятичной коррекции DAA
и DAS.
PF (разряд 2) – флаг чётности. Устанавливается, если младший байт результата операции содержит чётное число единичных разрядов, сбрасывается в противном случае.
CF (разряд 0) – флаг переноса. Устанавливается при возникновении переноса или заёма из/в старший разряд результата при выполнении команд сложения и вычитания, а также содержит значение выдвигаемого разряда в операциях сдвига.
При описании каждой инструкции будет указано, какие разряды регистра Flags могут быть изменены при её выполнении и в каких случаях это происходит.
Содержимое регистра флагов целиком доступно только для инструкций PUSHF
и POPF, которые соответственно сохраняют его значение в стеке или извлекают из стека. Младший байт регистра Flags может быть загружен в регистр AH инструкцией LAHF, содержимое регистра AH может быть переслано в младший байт регистра Flags посредством инструкции SAHF. Кроме того, при возникновении прерывания состояние регистра Flags сохраняется в стеке. Инструкция IRET, обеспечивающая возврат из прерывания, подобно инструкции POPF восстанавливает содержимое регистра флагов из стека.
Некоторые разряды регистра флагов могут быть проверены или изменены с помощью предназначенных для этого инструкций микропроцессора.
Для арифметико-логических команд содержимое регистра Flags напрямую недоступно.
Регистровые операнды
В командах обработки данных регистры общего назначения могут использоваться для хранения значений операндов. В этом случае говорят о регистровой адресации. Например, команда MOV AX,BX
пересылает содержимое регистра BX в регистр AX.
Сегментные регистры могут использоваться в качестве операндов только в некоторых командах пересылки, а именно в инструкциях MOV, PUSH
и POP. Сегментный регистр CS может служит источником в инструкции MOV, но не может служить приёмником. Он не может также использоваться в команде POP.
Регистр флагов и указатель инструкции не могут использоваться в качестве явно задаваемых операндов.
Регистры микропроцессора
С точки зрения программиста микропроцессор 8086 включает следующие регистры:
– регистры общего назначения;
– сегментные регистры;
– регистр флагов;
– регистр указателя инструкции.
Регистры общего назначения
Процессор 8086 имеет восемь 16-разрядных регистров общего назначения, обозначаемых AX, BX, CX, DX, SI, DI, BP и SP.
Старший и младший байты регистров AX, BX, CX и DX могут использоваться отдельно. Они носят обозначения AH, BH, CH и DH для старших байтов и AL, BL, CL и DL для младших байтов.
Несмотря на то, что эти регистры именуются регистрами общего назначения, каждый из них имеет специальные функции, которые не могут быть переданы какому-либо другому регистру. Общим является то, что все регистры общего назначения могут использоваться в командах пересылки, сложения, вычитания и логических операциях. О специальном назначении каждого регистра будет упоминаться в описании тех функций микропроцессора, где этот регистр используется. Ниже приведён краткий список специфических особенностей использования этих регистров.
Регистр AX является одним из операндов команд умножения и деления; хранит операнд, подвергающийся десятичной или символьной коррекции в операциях двоично-десятичной арифметики; используется в командах ввода-вывода в качестве регистра данных.
Регистр BX используется при адресации операндов.
Регистр CX содержит счётчик повторения цикла или количество разрядов, на которое производится сдвиг операнда в инструкциях сдвига.
Регистр DX расширяет разрядность регистра AX в операциях умножения, деления и двойного сдвига; он содержит адрес порта ввода-вывода в инструкциях ввода-вывода.
Регистр SI содержит смещение строки-источника в строковых операциях и может использоваться при адресации операндов.
Регистр DI содержит смещение строки-приёмника в строковых операциях и может использоваться при адресации операндов.
Регистр BP используется при адресации данных, расположенных в сегменте стека; может использоваться при адресации данных, расположенных в других сегментах.
Регистр SP является указателем стека.
REP/REPcc – повторение строковой операции
F3 A4 | REP MOVSB | пересылка CX байтов из DS:SI в ES:DI | |||
F3 A5 | REP MOVSW | пересылка CX слов из DS:SI в ES:DI | |||
F3 AC | REP LODSB | загрузка CX байтов из DS:SI в AL | |||
F3 AD | REP LODSW | загрузка CX слов из DS:SI в AX | |||
F3 AA | REP STOSB | запись CX байтов из AL в ES:DI | |||
F3 AB | REP STOSW | запись CX слов из AX в ES:DI | |||
F3 A6 | REPE CMPSB | сравнение CX байтов в DS:SI и ES:DI до несовпадения | |||
F3 A7 | REPE CMPSW | сравнение CX слов в DS:SI и ES:DI до несовпадения | |||
F3 AE | REPE SCASB | поиск байта, отличающегося от AL, в CX байтах в ES:DI | |||
F3 AF | REPE SCASW | поиск слова, отличающегося от AX, в CX словах в ES:DI | |||
F2 A6 | REPNE CMPSB | сравнение CX байтов в DS:SI и ES:DI до совпадения | |||
F2 A7 | REPNE CMPSW | сравнение CX слов в DS:SI и ES:DI до совпадения | |||
F2 AE | REPNE SCASB | поиск байта, совпадающего с AL, в CX байтах в ES:DI | |||
F2 AF | REPNE SCASW | поиск слова, совпадающего с AX, в CX словах в ES:DI |
Описание.
Префикс повторения используется совместно с инструкциями обработки строк. Он обеспечивает многократное повторение одной и той же операции до исчерпания счётчика или до выполнения заданного условия.
Счётчик находится в регистре CX. После каждого выполнения инструкции, употреблённой с префиксом повторения, содержимое CX уменьшается на единицу и проверяется на равенство нулю. Если нуль ещё не достигнут, снова выполняется инструкция, уменьшается и проверяется CX и т.д. Если же в результате вычитания содержимое CX обнулилось, операция прекращается. Таким образом, операция может быть повторена от одного до 65536 раз.
Помимо завершения операции по обнулению счётчика, в некоторых инструкциях предусмотрено её завершение при выполнении определённого условия, а именно равенства или неравенства флажка ZF нулю.
Логически имеются три разновидности префикса повторения, которым соответствуют пять мнемоник и два однобайтовых кода операции:
– простое повторение – префикс REP, код операции F3; операция заканчивается, когда содержимое регистра CX обнуляется;
– повторение, пока соблюдается равенство – префикс REPE/REPZ, код операции F3; операция заканчивается, когда содержимое регистра CX обнуляется или когда сбрасывается флажок ZF;
– повторение, пока равенство не соблюдается – префикс REPNE/REPNZ, код операции F2; операция заканчивается, когда содержимое регистра CX обнуляется или когда устанавливается флажок ZF.
С инструкциями MOVS, LODS, STOS
может применяться только обычный префикс повторения REP. Когда он используется, операция продолжает выполняться до тех пор, пока содержимое регистра CX не станет равным нулю.
С инструкциями CMPS и SCAS употребляются префиксы REPE/REPZ
и REPNE/REPNZ. Первый префикс обеспечивает прекращение операции при исчерпании счётчика или при сбросе флажка ZF в нуль; последнее событие имеет место, когда обнаружено неравенство сравниваемых байтов или слов. Второй префикс обеспечивает прекращение операции при исчерпании счётчика или при установке флажка ZF в единицу, что происходит при обнаружении равенства сравниваемых байтов или слов.
Флажки самим префиксом не изменяются, однако инструкции SCAS и CMPS, которые могут употребляться вместе с префиксом повторения, изменяют их.
RET – возврат из процедуры
C3 | RET | Ближний возврат из процедуры | |||
CB | RET | Дальний возврат из процедуры | |||
C2 iw | RET imm16 | Ближний возврат из процедуры с очисткой стека | |||
CA iw | RET imm16 | Дальний возврат из процедуры с очисткой стека |
Описание.
Инструкция RET
обеспечивает возврат из процедуры.
Адрес возврата должен храниться в вершине стека. Для операции ближнего возврата он занимает два байта, для операции дальнего возврата – четыре байта. Процессор извлекает адрес возврата и заносит его в регистры CS (только при дальнем возврате) и IP, при этом содержимое указателя стека SP увеличивается на 2 или 4.
Разновидность инструкции RET, обеспечивающая очистку стека, дополнительно прибавляет к содержимому SP указанную в инструкции 16-разрядную величину, что освобождает в стеке заданное число байтов.
Флажки не изменяются.
ROL – циклический сдвиг влево
D0 /0 | ROL r/m8, 1 | циклический сдвиг r/m8 влево на 1 разряд через CF | |||
D2 /0 | ROL r/m8, CL | циклический сдвиг r/m8 влево на CL разрядов через CF | |||
D1 /0 | ROL r/m16, 1 | циклический сдвиг r/m16 влево на 1 разряд через CF | |||
D3 /0 | ROL r/m16, CL | циклический сдвиг r/m16 влево на CL разрядов через CF |
Описание.
Эта инструкция производит циклический сдвиг содержимого своего операнда влево на указанное вторым операндом число разрядов.
Сдвиг выполняется по следующей схеме:
---------------¬
---¬ ¦ ----------¬ ¦
¦CF¦<-+-+ операнд
¦<--
L--- L----------
Имеются две разновидности сдвига: одноразрядный и многоразрядный. В последнем случае количество разрядов, на которое производится сдвиг, должно быть предварительно занесено в регистр CL.
Флажок CF содержит значение последнего выдвинутого из операнда разряда.
Значение флажка OF в операции многоразрядного сдвига не определено. В операции одноразрядного сдвига он представляет собой результат операции “исключающее ИЛИ” между значением старшего разряда результата и содержимым флажка CF после выполнения сдвига. Таким образом, единичное значение флажка OF свидетельствует о том, что содержимое старшего разряда результата отличается от его исходного значения, а нулевое значение – что старший разряд операнда не изменился.
Флажки SF, ZF, AF и PF не изменяются.
ROR – циклический сдвиг вправо
D0 /1 | ROR r/m8, 1 | циклический сдвиг r/m8 вправо на 1 разряд через CF | |||
D2 /1 | ROR r/m8, CL | циклический сдвиг r/m8 вправо на CL разрядов через CF | |||
D1 /1 | ROR r/m16, 1 | циклический сдвиг r/m16 вправо на 1 разряд через CF | |||
D3 /1 | ROR r/m16, CL | циклический сдвиг r/m16 вправо на CL разрядов через CF |
Описание.
Эта инструкция производит циклический сдвиг содержимого своего операнда вправо на указанное вторым операндом число разрядов.
Сдвиг выполняется по следующей схеме:
---------------¬
¦ ----------¬ ¦ ---¬
L->¦ операнд +-+->¦CF¦
L---------- L---
Имеются две разновидности сдвига: одноразрядный и многоразрядный. В последнем случае количество разрядов, на которое производится сдвиг, должно быть предварительно занесено в регистр CL.
Флажок CF содержит значение последнего выдвинутого из операнда разряда.
Значение флажка OF в операции многоразрядного сдвига не определено. В операции одноразрядного сдвига он представляет собой результат операции “исключающее ИЛИ” между содержимым двух самых старших разрядов результата. Таким образом, единичное значение флажка OF указывает, что операнд сменил свой знак, а нулевое – что знак остался неизменным.
Флажки SF, ZF, AF и PF не изменяются.
SAHF – загрузка AH в регистр флагов
9E | SAHF | загрузка содержимого регистра AH в младший байт регистра FLAGS |
Описание.
Значащие разряды младшего байта регистра FLAGS устанавливаются в соответствии с соответствующими разрядами регистра AH. Содержимое зарезервированных разрядов (битов 1, 3 и 5) не изменяется.
Флажки
устанавливаются в соответствии с содержимым AH.
SAL – арифметический сдвиг влево
D0 /4 | SAL r/m8, 1 | арифметический сдвиг r/m8 влево на 1 разряд | |||
D2 /4 | SAL r/m8, CL | арифметический сдвиг r/m8 влево на CL разрядов | |||
D1 /4 | SAL r/m16, 1 | арифметический сдвиг r/m16 влево на 1 разряд | |||
D3 /4 | SAL r/m16, CL | арифметический сдвиг r/m16 влево на CL разрядов |
Описание.
Эта инструкция производит арифметический (он же логический – см. инструкцию SHL) сдвиг содержимого своего операнда влево на указанное вторым операндом число разрядов.
Сдвиг выполняется по следующей схеме:
---¬ ----------¬
¦CF¦<--+ операнд ¦<- 0
L--- L----------
Имеются две разновидности сдвига: одноразрядный и многоразрядный. В последнем случае количество разрядов, на которое производится сдвиг, должно быть предварительно занесено в регистр CL.
Флажок CF содержит значение последнего выдвинутого из операнда разряда.
Значение флажка OF в операции многоразрядного сдвига не определено. В операции одноразрядного сдвига он представляет собой результат операции “исключающее ИЛИ” между значением старшего разряда результата и содержимым флажка CF после выполнения сдвига. Таким образом, единичное значение флажка OF свидетельствует о том, что содержимое старшего разряда результата отличается от его исходного значения, а нулевое значение – что старший разряд операнда не изменился.
Флажки SF, ZF и PF устанавливаются в соответствии с полученным результатом.
Значение флажка AF не определено.
SAR – арифметический сдвиг вправо
D0 /7 | SAR r/m8, 1 | арифметический сдвиг r/m8 вправо на 1 разряд | |||
D2 /7 | SAR r/m8, CL | арифметический сдвиг r/m8 вправо на CL разрядов | |||
D1 /7 | SAR r/m16, 1 | арифметический сдвиг r/m16 вправо на 1 разряд | |||
D3 /7 | SAR r/m16, CL | арифметический сдвиг r/m16 вправо на CL разрядов |
Описание.
Эта инструкция производит арифметический сдвиг содержимого своего операнда вправо на указанное вторым операндом число разрядов.
Сдвиг выполняется по следующей схеме:
----¬
¦ -+--------¬ ---¬
L->¦ операнд +-->¦CF¦
L---------- L---
Имеются две разновидности сдвига: одноразрядный и многоразрядный. В последнем случае количество разрядов, на которое производится сдвиг, должно быть предварительно занесено в регистр CL.
Флажок CF содержит значение последнего выдвинутого из операнда разряда.
Флажок OF сбрасывается, поскольку при арифметическом сдвиге вправо состояние старшего (знакового) разряда операнда никогда не изменяется.
Флажки SF, ZF, AF и PF не изменяются.
SBB – двоичное вычитание с заёмом
18 /r | SBB r/m8, r8 | r/m8:= r/m8 – r8
– CF | |||
19 /r | SBB r/m16, r16 | r/m16:= r/m16
– r16 – CF | |||
1A /r | SBB r8, r/m8 | r8:= r8
– r/m8 – CF | |||
1B /r | SBB r16, r/m16 | r16:= r16 –
r/m16 – CF | |||
1C ib | SBB AL, imm8 | AL:= AL – imm8 – CF | |||
1D iw | SBB AX, imm16 | AX:= AX – imm16 – CF | |||
80 /3 ib | SBB r/m8, imm8 | r/m8:= r/m8
– imm8 – CF | |||
81 /3 iw | SBB r/m16, imm16 | r/m16:= r/m16
– imm16 – CF | |||
83 /3 ib | SBB r/m16, imm8 | r/m16:= r/m16 – imm8 – CF |
Описание.
Эта инструкция обеспечивает вычитание двух 8- или 16-разрядных двоичных чисел с учётом значения входного заёма, определяемого флажком CF.
При вычитании 8-разрядного второго операнда из 16-разрядного первого (код операции 83) перед выполнением операции производится расширение знака второго операнда.
Флажки OF, SF, ZF, AF, CF и PF устанавливаются по обычным правилам. Флажок CF свидетельствует о наличии заёма в старший разряд результата.
SCAS – сканирование строки
AE | SCASB | поиск байта AL в [ES:DI] | |||
AF | SCASW | поиск слова AX в [ES:DI] |
Описание.
Эта инструкция производит поиск байта или слова, содержащегося в регистре AL/AX, в строке по адресу [ES:DI].
Сравнение выполняется путём выполнения вычитания значений операндов. Результат вычитания теряется, но по нему устанавливаются флажки в регистре FLAGS.
Инструкция SCAS относится к группе инструкций обработки строк. Операнд находится в памяти по адресу, содержащемуся в регистровой паре ES:DI. Сегментный регистр ES не может быть заменён другим сегментным регистром с помощью префикса замены сегмента. Операндом-приёмником всегда является регистр AL или AX.
После загрузки байта или слова в аккумулятор содержимое регистра DI увеличивается (DF=0) или уменьшается (DF=1) на 1 или 2 в зависимости от размера операнда.
Флажки изменяются в соответствии с результатами выполнения сравнения.
Сегментация
Микропроцессор 8086 для формирования 20-разряного физического адреса использует 16-разрядные селекторы сегментов и смещения.
Селекторы сегментов
хранятся в сегментных регистрах (см. подраздел 2.3.2 “Сегментные регистры”). В зависимости от того, с какой целью выполняется обращение к памяти, процессор использует один из четырёх имеющихся селекторов сегментов. Так, если обращение производится для выборки кода команды, используется селектор сегмента кода, хранящийся в регистре CS, а если происходит запись данных в стек – селектор сегмента стека из регистра SS.
Смещение
формируется в процессе выполнения команды и определяет местоположение требуемой информации внутри сегмента. Например, при выборке кода команды производится чтение байта памяти, хранящегося по смещению из регистра IP (см. подраздел 2.3.4 “Указатель инструкции”) в сегменте кода, селектор которого находится в регистре CS. Поскольку смещение является 16-разрядным, размер сегмента ограничен 64 Кбайтами.
Физический адрес
вычисляется путём сложения 16-разрядного смещения с селектором соответствующего сегмента, сдвинутым влево на четыре разряда. Так как селектор сегмента является 16-разрядной величиной, сдвиг преобразует его в 20-разрядное число, младшие четыре разряда которого содержат нули. Схематически это можно представить следующим образом:
-----T----T----T----¬
¦ с м е щ е н и е ¦
L----+----+----+-----
+
-----T----T----T----T----¬
¦ с е л е к т о р ¦0000¦
L----+----+----+----+-----
--------------------------
-----T----T----T----T----¬
¦ физический адрес ¦
L----+----+----+----+-----
Перенос, который может возникнуть из старшего (19-го) разряда физического адреса в процессе сложения, игнорируется[1]. Таким образом, при доступе к слову памяти, расположенному по смещению 000F16 в сегменте с селектором FFFF16, физический адрес младшего байта этого слова будет равен FFFFF16, а старшего – 0000016.
Легко заметить, что для доступа к одной и той же физической ячейке памяти могут использоваться различные комбинации селекторов и смещений.
Например, физический адрес 0100016 может быть получен при селекторе 000016 и смещении 100016, селекторе 010016 и смещении 000016, а также при множестве других значений селекторов и смещений. Подобный подход к формированию физического адреса оказался весьма неудобным и способствует возникновению трудноуловимых ошибок.
Программист работает с логическими адресами, состоящими из селекторов и смещений. Логический адрес записывается в виде “селектор :
смещение”. Большинство машинных инструкций, обращающихся к памяти, позволяют задать только смещение требуемого операнда, а селектор находится в том или ином сегментном регистре. Смещение в таких инструкциях называется эффективным адресом и вычисляется в процессе выполнения команды. Подробно правила вычисления эффективного адреса описаны в подразделе 2.4.1 “Адресация операндов”.
Если данные размещаются в сегменте, селектор которого не загружен в требуемый сегментный регистр, перед выполнением доступа к этим данным необходимо загрузить селектор содержащего их сегмента в тот или иной сегментный регистр.
Команды переходов позволяют указать либо только смещение инструкции, которая должна выполняться следующей, либо и селектор сегмента, и смещение следующей инструкции. В первом случае говорят о ближнем (near) переходе – новая инструкция находится в том же сегменте, что и команда перехода. Во втором случае переход будет дальним (far) – новая инструкция находится в другом сегменте.
В языках высокого уровня имеются понятия ближних и дальних указателей. Ближние указатели состоят только из смещения; подразумевается, что это смещение относится к текущему сегменту данных. Дальние указатели состоят из селектора сегмента и смещения; компилятор, обрабатывая дальние указатели, должен обеспечить загрузку селектора в требуемый сегментный регистр.
Сегментные регистры
Процессор 8086 содержит четыре 16-разрядных сегментных регистра: CS, DS, ES и SS, называемые соответственно сегментными регистрами кода, данных, дополнительных данных и стека.
Процессор использует содержимое сегментных регистров (так называемые селекторы сегментов) для формирования 20-разрядных физических адресов памяти, о чём говорилось выше, в подразделе 2.2.2 “Сегментация”. При обращениях к кодам команд всегда используется сегментный регистр CS, а при обращении к стеку (с использованием указателя стека или при адресации посредством регистра BP) – сегментный регистр SS, причём если адресация данных производится с помощью регистра BP, вместо сегментного регистра SS можно указать любой другой сегментный регистр. При обращении к данным в большинстве случаев по умолчанию используется регистр сегментный регистр DS, однако вместо него в этих ситуациях можно использовать любой другой сегментный регистр. Сегментный регистр ES используется при доступе к строкам-приёмникам в строковых операциях, в этом качестве он не может быть заменён каким-либо другим сегментным регистром.
Сегментные регистры не могут являться операндами арифметико-логических инструкций. В регистры DS, ES и SS значение может быть загружено из какого-либо регистра общего назначения с помощью инструкции MOV
либо извлечено из вершины стека инструкцией POP. Регистр CS не может быть загружен с помощью инструкции MOV
или POP, новое значение в него загружается только при выполнении операций длинных переходов (инструкции JMP, CALL и RET), при возврате из прерывания (инструкция IRET) и при возникновении прерывания. Короткие переходы не изменяют регистр CS. Содержимое всех четырёх сегментных регистров может быть переслано в любой регистр общего назначения инструкцией MOV или занесено в стек инструкцией PUSH.
SHL – логический сдвиг влево
D0 /4 | SHL r/m8, 1 | логический сдвиг r/m8 влево на 1 разряд | |||
D2 /4 | SHL r/m8, CL | логический сдвиг r/m8 влево на CL разрядов | |||
D1 /4 | SHL r/m16, 1 | логический сдвиг r/m16 влево на 1 разряд | |||
D3 /4 | SHL r/m16, CL | логический сдвиг r/m16 влево на CL разрядов |
Описание.
Эта инструкция производит логический
(он же арифметический – см. инструкцию SAL) сдвиг содержимого своего операнда влево на указанное вторым операндом число разрядов.
Сдвиг выполняется по следующей схеме:
---¬ ----------¬
¦CF¦<--+ операнд ¦<- 0
L--- L----------
Имеются две разновидности сдвига: одноразрядный и многоразрядный. В последнем случае количество разрядов, на которое производится сдвиг, должно быть предварительно занесено в регистр CL.
Флажок CF содержит значение последнего выдвинутого из операнда разряда.
Значение флажка OF в операции многоразрядного сдвига не определено. В операции одноразрядного сдвига он представляет собой результат операции “исключающее ИЛИ” между значением старшего разряда результата и содержимым флажка CF после выполнения сдвига. Таким образом, единичное значение флажка OF свидетельствует о том, что содержимое старшего разряда результата отличается от его исходного значения, а нулевое значение – что старший разряд операнда не изменился.
Флажки SF, ZF и PF устанавливаются в соответствии с полученным результатом.
Значение флажка AF не определено.
SHR – логический сдвиг вправо
D0 /5 | SHR r/m8, 1 | логический сдвиг r/m8 вправо на 1 разряд | |||
D2 /5 | SHR r/m8, CL | логический сдвиг r/m8 вправо на CL разрядов | |||
D1 /5 | SHR r/m16, 1 | логический сдвиг r/m16 вправо на 1 разряд | |||
D3 /5 | SHR r/m16, CL | логический сдвиг r/m16 вправо на CL разрядов |
Описание.
Эта инструкция производит логический сдвиг содержимого своего операнда вправо на указанное вторым операндом число разрядов.
Сдвиг выполняется по следующей схеме:
----------¬ ---¬
0 ->¦ операнд +-->¦CF¦
L---------- L---
Имеются две разновидности сдвига: одноразрядный и многоразрядный. В последнем случае количество разрядов, на которое производится сдвиг, должно быть предварительно занесено в регистр CL.
Флажок CF содержит значение последнего выдвинутого из операнда разряда.
Значение флажка OF в операции многоразрядного сдвига не определено. В операции одноразрядного сдвига устанавливается, если перед выполнением сдвига старший разряд операнда содержал единицу, и сбрасывается в противном случае. Поскольку после выполнения сдвига старший разряд будет содержать нуль, флажок OF показывает, произошла ли смена значения старшего разряда операнда.
Флажки SF, ZF, AF и PF не изменяются.
Символьная информация
Символьная информация хранится в памяти вычислительной машины. Набор строковых операций позволяет одной командой обработать один или два байта памяти, а также организовать повторение строковых команд. Максимальное число повторений – 65536. Из-за особенностей адресации (использования 16-разрядных сегментного адреса и смещения) максимальный размер строки ограничен 65536 символами, хотя счётчик повторений при использовании операций, работающих со словами, позволяет обработать вдвое больший объём данных.
Строковые операции могут выполняться как слева направо (в сторону увеличения адресов), так и справа налево (в сторону уменьшения адресов).
Система команд
Микропроцессор 8086 насчитывает 135 различных команд. В этой главе описываются все инструкции и префиксы, используемые микропроцессором, и указываются возможные форматы этих команд. Инструкции математического сопроцессора, “дополняющие” команду ESC микропроцессора 8086, не рассматриваются, поскольку они не относятся к системе команд микропроцессора 8086 и реализуются сопроцессором 8087 (КР1810ВМ87).
STC – установка флага переноса
F9 | STC | CF:= 1 |
Описание.
Устанавливается флажок переноса CF регистра FLAGS.
Флажок CF устанавливается, остальные флажки не изменяются.
STD – установка флага направления
FD | STD | DF:= 1 |
Описание.
Устанавливается флажок переноса DF регистра FLAGS.
Установка флажка DF обеспечивает выполнение строковых операций с автодекрементом (уменьшением адресов операндов, находящихся в регистрах SI и DI).
Флажок CF устанавливается, остальные флажки не изменяются.
Стек
Микропроцессор 8086 поддерживает аппаратный стек. Регистровая пара SS:SP (селектор сегмента находится в регистре SS, а смещение – в регистре SP) указывает на слово, являющееся вершиной стека. Регистр SP должен содержать чётное значение, т.е. стек всегда должен быть выровнен на границу слова. При записи или чтении байта в стек будет помещено или из стека будет извлечено слово (два байта).
Стек микропроцессора 8086 растёт вниз. Это означает, что при записи слова в стек содержимое регистра SP уменьшается на два, после чего производится запись в стек по адресу SS:SP. При извлечении данных из стека сначала считывается слово по адресу SS:SP, а затем содержимое SP увеличивается на два. Если операция выполнялась над байтом, то этот байт будет младшим байтом слова, записываемого или извлекаемого из стека. Значение старшего байта при записи предсказать невозможно; при чтении из стека его значение игнорируется.
Запись в стек имеет место в следующих случаях:
– при выполнении инструкции PUSH, записывающей в стек значение своего операнда;
– при выполнении инструкции PUSHF, записывающей в стек содержимое регистра флагов;
– при выполнении инструкции CALL, записывающего в стек адрес возврата из подпрограммы (адрес состоит из одного или двух слов в зависимости от того, выполняется ли ближний или дальний переход);
– при выполнении прерывания (в стек записывается три слова – содержимое регистра флагов и адрес возврата из прерывания).
Чтение из стека происходит:
– при выполнении инструкций POP
и POPF, обратных инструкциям PUSH и PUSHF;
– при выполнении инструкции RET, обеспечивающей возврат из подпрограммы (извлекается одно или два слова в зависимости от того, какой возврат – ближний или дальний – выполняется);
– при выполнении инструкции возврата из прерывания IRET (извлекается три слова – дальний адрес возврата из подпрограммы и содержимое слова флагов).
Для доступа к данным в стеке без их извлечения ячейки, составляющие стек, могут адресоваться как обычные ячейки памяти. Как правило, базовый адрес, используемый для доступа к ячейкам стека, содержится в регистре BP. Использование регистра SP для таких доступов невозможно.
STI – установка флага разрешения прерывания
FB | STI | IF:= 1 |
Описание.
Устанавливается флажок переноса IF регистра FLAGS.
Когда флажок IF установлен, разрешена обработка внешних прерываний.
Флажок IF устанавливается, остальные флажки не изменяются.
STOS – запись строки
AA | STOSB | запись байта из AL в [ES:DI] | |||
AB | STOSW | запись слова из AX в [ES:DI] |
Описание.
Эта инструкция записывает содержимое регистра AL или AX по адресу ES:DI.
Инструкция STOS относится к группе инструкций обработки строк. Операнд-приёмник находится в памяти по адресу, содержащемуся в регистровой паре ES:DI. Сегментный регистр ES не может быть заменён другим сегментным регистром с помощью префикса замены сегмента. Операндом-источником всегда является регистр AL или AX.
После записи байта или слова из аккумулятора в память содержимое регистра DI увеличивается (DF=0) или уменьшается (DF=1) на 1 или 2 в зависимости от размера операнда.
Флажки не изменяются.
SUB – двоичное вычитание
28 /r | SUB r/m8, r8 | r/m8:= r/m8 – r8 | |||
29 /r | SUB r/m16, r16 | r/m16:= r/m16
– r16 | |||
2A /r | SUB r8, r/m8 | r8:= r8
– r/m8 | |||
2B /r | SUB r16, r/m16 | r16:= r16 –
r/m16 | |||
2C ib | SUB AL, imm8 | AL:= AL – imm8 | |||
2D iw | SUB AX, imm16 | AX:= AX – imm16 | |||
80 /5 ib | SUB r/m8, imm8 | r/m8:= r/m8
– imm8 | |||
81 /5 iw | SUB r/m16, imm16 | r/m16:= r/m16
– imm16 | |||
83 /5 ib | SUB r/m16, imm8 | r/m16:= r/m16 – imm8 |
Описание.
Эта инструкция обеспечивает вычитание двух 8- или 16-разрядных двоичных чисел.
При вычитании 8-разрядного второго операнда из 16-разрядного первого (код операции 83) перед выполнением операции производится расширение знака второго операнда.
Флажки OF, SF, ZF, AF, CF и PF устанавливаются по обычным правилам. Флажок CF свидетельствует о наличии заёма в старший разряд результата.
Таблица векторов прерываний
Как уже упоминалось, микропроцессор 8086 использует векторную систему прерываний, при которой каждому обработчику прерывания назначается свой номер, называемый вектором. Всего имеется 256 векторов прерываний.
Таблица векторов прерываний занимает младший 1 Кбайт физического адресного пространства микропроцессора. Каждому вектору в ней соответствует четырёхбайтовая область. Первое слово любого вектора прерывания содержит смещение, а второе слово – селектор сегмента обработчика прерывания, назначенного этому вектору. Таким образом, каждый вектор является дальним адресом (парой “сегмент : смещение”) соответствующего обработчика прерывания.
TEST – логическое сравнение
84 /r | TEST r/m8, r8 | r/m8 AND r8 | |||
85 /r | TEST r/m16, r16 | r/m16 AND r16 | |||
A8 ib | TEST AL, imm8 | AL AND imm8 | |||
A9 iw | TEST AX, imm16 | AX AND imm16 | |||
F6 /0 ib | TEST r/m8, imm8 | r/m8 AND imm8 | |||
F7 /0 iw | TEST r/m16, imm16 | r/m16 AND imm16 |
Описание.
Эта инструкция выполняет логическое сравнение двух операндов.
Сравнение выполняется путём выполнения операции “логическое И” между разрядами первого и второго операндов. Результат операции теряется, но производится соответствующая установка флажков.
Флажки OF и CF очищаются.
Флажки SF, ZF и PF устанавливаются в соответствии с полученным результатом.
Состояние флажка AF не определено.
Указатель инструкции
В состав микропроцессора 8086 входит 16-разрядный указатель инструкции IP. Он содержит смещение следующей команды в текущем сегменте кода (сегментный адрес хранится в регистре сегмента кода CS). При выборке очередной команды содержимое IP увеличивается на количество байтов, входящих в код команды.
Регистр IP не может напрямую использоваться в арифметико-логических командах. Его содержимое сохраняется в стеке при обращении к подпрограмме с помощью инструкции CALL, а также при возникновении прерывания. Восстановление содержимого регистра IP из стека возможно только с помощью инструкций возврата из прерывания IRET
и возврата из подпрограммы RET. Кроме того, в регистр IP загружается новое значение при выполнении любых инструкций переходов.
Внешние прерывания
Внешние прерывания возникают вне микропроцессора. Запросы прерываний поступают по специальным входным линиям процессорной микросхемы. Различают немаскируемые и маскируемые внешние прерывания.
Выполнение инструкций
В зависимости от назначения все инструкции можно разделить на несколько групп:
– инструкции пересылки;
– арифметико-логические инструкции;
– инструкции сдвигов;
– инструкции обработки строк;
– инструкции переходов;
– инструкции управления и вспомогательные;
– префиксы инструкций.
Первые три категории команд (пересылки, арифметико-логические и сдвигов) можно назвать инструкциями обработки данных. Инструкции обработки строк стоят несколько особняком, поскольку они отличаются от команд обработки данных способом определения местоположения своих операндов. Инструкции переходов осуществляют передачу управления в процессе выполнения программы. Инструкции управления и вспомогательные в обычных программах применяются редко, их основное назначение – управление состоянием процессора. Префиксы инструкций самостоятельного значения не имеют и применяются в составе других команд, модифицируя их выполнение.
Выполнение каждой инструкции складывается из следующих шагов:
– выборки из памяти и дешифровки кода команды;
– определения местоположения операндов, если они явно задаются кодом команды (некоторые инструкции не имеют операндов вообще, в некоторых других местоположение операндов подразумевается);
– вычисления эффективного адреса операнда в памяти, если таковой имеется;
– собственно выполнения инструкции.
WAIT – ожидание сопроцессора
9B | WAIT | переход в ожидание готовности сопроцессора |
Описание.
Эта инструкция приостанавливает дальнейшее выполнение программы до поступления сигнала готовности от сопроцессора.
Команда WAIT используется после инструкций математического сопроцессора. Она приостанавливает выполнение программы до тех пор, пока не будет закончена обработка последней команды сопроцессора.
Флажки не изменяются.
XCHG – обмен информацией
90+rw | XCHG AX, r16 | AX - r16 | |||
90+rw | XCHG r16, AX | r16 - AX | |||
86 /r | XCHG r/m8, r8 | r/m8 - r8 | |||
86 /r | XCHG r8, r/m8 | r8 - r/m8 | |||
87 /r | XCHG r/m16, r16 | r/m16 - r16 | |||
87 /r | XCHG r16, r/m16 | r16 - r/m16 |
Описание.
Эта инструкция меняет местами содержимое своих операндов.
Флажки не изменяются.
XLATB – табличная перекодировка
D7 | XLATB | AL:= [BX+AL] |
Описание.
Эта инструкция перекодирует по таблице значение регистра AL.
Начальный адрес 256-байтовой таблицы перекодировки содержится в регистре BX. Перекодировка заключается в том, что из ячейки таблицы, номер которой содержится в регистре AL, извлекается байт и заносится в регистр AL.
Флажки не изменяются.
XOR – исключающее ИЛИ
30 /r | XOR r/m8, r8 | r/m8:= r/m8
XOR r8 | |||
31 /r | XOR r/m16, r16 | r/m16:= r/m16 XOR r16 | |||
32 /r | XOR r8, r/m8 | r8:= r8 XOR r/m8 | |||
33 /r | XOR r16, r/m16 | r16:= r16 XOR r/m16 | |||
34 ib | XOR AL, imm8 | AL:= AL XOR imm8 | |||
35 iw | XOR AX, imm16 | AX:= AX XOR imm16 | |||
80 /6 ib | XOR r/m8, imm8 | r/m8:= r/m8 XOR imm8 | |||
81 /6 iw | XOR r/m16, imm16 | r/m16:= r/m16 XOR imm16 |
Описание.
Выполняется операция “исключающее ИЛИ” между операндами инструкции, результат заносится на место первого операнда.
Флажки OF и CF очищаются.
Флажки SF, ZF и PF устанавливаются в соответствии с результатом.
Состояние флажка AF не определено.
при выполнении операции сложения распакованных
Инструкция 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, содержащий мощную собственную систему команд. Её описание не входит в задачу данной публикации.