- •Введение
- •1.1. Основные направления эволюции микрокомпьютеров
- •1.2. Основные сведения о компьютерах
- •1.3. Представление чисел
- •Заключение
- •Лекция 2 машинная организация процессора 80286
- •2.1. Введение
- •2.2. Структура памяти
- •2.3. Сегментация памяти
- •2.4. Структура ввода-вывода
- •2.5. Регистры
- •2.6. Операнды и режимы адресации операндов
- •2.7. Замечания о режимах адресации
- •Глава 3 базовая система команд процессора 80286
- •3.1. Нотация языка ассемблера
- •3.2. Команды передач данных
- •3.3. Арифметические команды
- •Лекция 6. Цепочечные команды
- •Лекция 7. Команды безусловной передачи управления
- •Лекция 8. Команды условной передачи управления
- •Лекция 9. Прерывания
- •Int n
- •Лекция 10. Флажковые команды
- •3.10. Команды синхронизации
- •3.11. Поддержка языков высокого уровня
- •3.12. Замечания о префиксах
- •3.13. Воздействие на флажки
- •Заключение
3.12. Замечания о префиксах
Мы рассмотрели все три префиксных байта - байты замены сегмента, повторения и блокировки. В связи с этим возникают следующие вопросы: можно ли в любой команде использовать любой префикс, можно ли указать перед командой несколько префиксов, что произойдет, если команда с префиксом прерывается. Любой префикс можно использовать с любой командой за одним исключением. Исключение составляет префикс повторения, который можно указывать только в цепочечных примитивах. Указание его перед любой другой командой вызовет особый случай недействительной операции. Префикс блокировки предназначен для определенных команд (MOVS, INS и OUTS) и заставляет процессор выдать сигнал LOCK на время их выполнения. Этот сигнал обычно применяется для обеспечения процессору монопольного доступа к памяти в мультипроцессорных системах. Однако разрешается ввести префикс блокировки и в любой другой команде, которая даже не обращается к памяти. Наконец, префикс замены сегмента можно использовать с любой командой. Если команда обращается к операнду в памяти, префикс показывает сегмент операнда; в противном случае он не действует.
В общем, допускается применение префиксов в любой комбинации. Однако следует осторожно использовать вместе префиксы повторения и блокировки, так как это может запретить доступ к памяти другим процессорам на относительно продолжительное время, т.е. на все время выполнения повторяющейся цепочечной команды.
В заключение рассмотрим прерывания команд с префиксами. Прерывания чаще всего распознаются между командами. Но если заставить прерывание ожидать завершения повторяющейся цепочечной команды, ожидание может оказаться (относительно) продолжительным. Поэтому процессор допускает обслуживание прерываний после любого повторения цепочечной команды. Когда происходят повторения, указатель команды содержит смещение (первого префиксного байта) команды. Если команда прерывается, сохраняется именно это смещение и с него возобновляется выполнение после обработки прерывания. Следовательно, если кроме префикса повторения команда содержит и другие префиксы, они будут частью команды при ее возобновлении. В микропроцессоре 8086 этого не было. (Отметим, что возобновленная цепочечная команда не повторяет сделанного ею до прерывания; счетчик в регистре СХ и указатели в регистрах SI и DI модифицировались в каждом повторении до прерывания и возобновление выполнения команды начинается с этих модифицированных значений.)
3.13. Воздействие на флажки
Ранее мы говорили о воздействии на флажки некоторых команд, а здесь мы объединим всю информацию и полностью рассмотрим функционирование флажков. Флажки IOPL и NT относятся к механизму защиты процессора и обсуждаются в гл. 5. Остальные флажки можно разделить на флажки состояния и флажки управления. Первые из них показывают определенные свойства результатов команд, а вторые - управляют работой процессора. В табл. 3.22 показаны команды, результаты которых влияют на флажки состояния, и команды, служащие для задания состояния флажков управления. Попробуем разобраться в поведении некоторых флажков.
|
|
|
|
Таблица 3. 22 Воздействие команд на флажки |
|
|
| ||||||||
|
А. Флажки состояния |
OF |
CF |
AF |
SF |
ZF |
PF | ||||||||
|
Сложение и вычитание |
|
|
|
|
|
| ||||||||
|
ADD, ADC, SUB, SBB |
+ |
+ |
+ |
+ |
+ |
+ | ||||||||
|
CMP, NEG, CMPS, SCAS |
+ |
+ |
+ |
+ |
+ |
+ | ||||||||
|
Инкремент и декремент |
|
|
|
|
|
| ||||||||
|
INC, DEC |
+ |
- |
+ |
+ |
+ |
+ | ||||||||
|
Умножение и деление |
|
|
|
|
|
| ||||||||
|
MUL, IMUL |
+ |
+ |
? |
? |
? |
? | ||||||||
|
DIV, IDIV |
? |
? |
? |
? |
? |
? | ||||||||
|
Десятичная арифметика |
|
|
|
|
|
| ||||||||
|
DAA, DAS, |
? |
+ |
+ |
+ |
+ |
+ | ||||||||
|
А. Флажки состояния |
OF |
CF |
AF |
SF |
ZF |
PF | ||||||||
|
AAA, AAS |
? |
+ |
+ |
? |
? |
? | ||||||||
|
AAM, AAD |
? |
? |
? |
+ |
+ |
+ | ||||||||
|
Булевы команды |
|
|
|
|
|
| ||||||||
|
AND, OR, XOR TEST |
0 |
0 |
? |
+ |
+ |
+ | ||||||||
|
Сдвиг и циклический сдвиг |
|
|
|
|
|
| ||||||||
|
SHL, SHR (единичный) |
+ |
+ |
? |
+ |
+ |
+ | ||||||||
|
SHL, SHR (переменный) |
? |
+ |
? |
+ |
+ |
+ | ||||||||
|
SAR |
0 |
+ |
? |
+ |
+ |
+ | ||||||||
|
ROL, ROR, RCL, RCR (единичный) |
+ |
+ |
- |
- |
- |
- | ||||||||
|
ROL, ROR, RCL, RCR (переменный) |
? |
+ |
- |
- |
- |
- | ||||||||
|
Восстановление флажков |
|
|
|
|
|
| ||||||||
|
POPF, IRET |
+ |
+ |
+ |
+ |
+ |
+ | ||||||||
|
SAHF |
- |
+ |
+ |
+ |
+ |
+ | ||||||||
|
Установки флажка переноса |
|
|
|
|
|
| ||||||||
|
STC |
- |
1 |
- |
- |
- |
- | ||||||||
|
CLC |
- |
0 |
- |
- |
- |
- | ||||||||
|
CMC |
- |
* |
- |
- |
- |
- | ||||||||
|
Б. Флажки управления |
DF |
IF |
TF |
|
|
| ||||||||
|
Восстановление флажков |
|
|
|
|
|
| ||||||||
|
POPF, IRET |
+ |
+ |
+ |
|
|
| ||||||||
|
Прерывания |
|
|
|
|
|
| ||||||||
|
INT, INTO |
- |
0 |
0 |
|
|
| ||||||||
|
Установки флажка управления |
|
|
|
|
|
| ||||||||
|
STD |
1 |
- |
- |
|
|
| ||||||||
|
CLD |
0 |
- |
- |
|
|
| ||||||||
|
Установки флажка прерывания |
|
|
|
|
|
| ||||||||
|
STI |
- |
1 |
- |
|
|
| ||||||||
|
CLI |
- |
0 |
- |
|
|
| ||||||||
|
ОБОЗНАЧЕНИЯ: + = изменяется 1 = устанавливается в 1 0 = сбрасывается в 0 * = инвертируется ? = не определён - = не изменяется |
|
|
|
|
|
| ||||||||
Команды сложения и вычитания воздействуют на все флажки состояния следующим образом: флажок переполнения OF и флажок переноса CF показывают, что знаковый или беззнаковый результат операции находится вне
диапазона представимых чисел; флажок вспомогательного переноса AF показывает необходимость коррекции в десятичной операции; флажки знака SF, нуля ZF и паритета PF сигнализируют о том, что результат отрицательный, нулевой или содержит четное число единиц.
К командам сложение и вычитания близки команды сравнения СМР, CMPS, SCAS и команда изменения знака NEG. Команды сравнения производят вычитание, и флажки отражают особенности результата вычитания. Команда NEG прибавляет 1 (после инвертирования всех бит), и флажки отражают результат этого сложения. Команда NEG устанавливает флажок CF в 1 в случае нулевого операнда, а флажок OF в случае, когда операнд равен -128 (8 бит) или -32 788 (16 бит).
Команды инкремента и декремента воздействуют на флажки состояния так же, как команды сложения и вычитания, но они не влияют на состояние флажка переноса. Благодаря этому цикл арифметики многократной точности приобретает следующий вид:
1. Инициализировать регистр SI на смещение младшего байта первого операнда.
2. Инициализировать регистр DI на смещение младшего байта второго операнда.
3. Сбросить флажок переноса CF (команда CLC).
4. Прибавить с переносом (команда ADC) байт, адресуемый регистром SI, к байту, адресуемому регистром DI.
5. Произвести инкремент (команда INC) содержимого регистра SI для указания на следующий старший байт первого операнда.
6. Произвести инкремент (команда INC) содержимого регистра DI для указания на следующий старший байт второго операнда.
7. Перейти к шагу 4, если операнды содержат дополнительные байты. Если бы команды INC (шаги 4 и 5) влияли на состояние флажка переноса, повторные выполнения команды ADC на шаге 4 не дали бы правильного результата.
Команды умножения (отличные от IMUL с непосредственным операндом) образуют результат двойной длины, поэтому в установке флажков необходимо учитывать 32 бита. Поскольку результаты всех других команд не превышают 16 бит, в процессоре потребовались бы специальные схемы только для одной команды умножения. Кроме того, неясно, что делать с полученными состояниями флажков. Чтобы упростить процессор, после команды умножения состояние большинства флажков оставлено неопределенным. Это означает, что процессор не пытается воздействовать на флажки каким-то регулярным способом; он просто выполняет команду как можно проще и игнорирует флажки. Не исключено, что в следующих моделях процессора команда будет
выполняться по-другому и давать другие состояния флажков.
После выполнения команды умножения полезно знать, не вышло ли за диапазон произведение, рассматриваемое как число одинарной длины (как число двойной длины, оно никогда не выходит за диапазон). Это позволяет умножить байт на второй байт и прибавить произведение к третьему байту. Поэтому состояния флажков OF и CF не остаются неопределенными; они показывают, не выходит ли знаковое или беззнаковое произведение за диапазон, если его считать числом одинарной длины.
Ради упрощения процессора после выполнения команды деления все флажки состояния не определены.
Единственным флажком состояния, который важен после коррекции десятичного сложения и вычитания, является флажок переноса CF (он требуется в арифметике многократной точности); все остальные флажки можно оставить неопределенными. Однако микропроцессор 8080 имеет единственную десятичную команду DAA, которая воздействует на все пять флажков состояния (флажок переполнения в этом микропроцессоре отсутствует). Поэтому ради совместимости команда DAA процессоров 8086 и 80286 действует так же. По той же причине совместимости команды DAS, AAA и AAS должны воздействовать на пять флажков; команда DAS так и делает, но трудности реализации заставили оставить неопределенными флажки SF, ZF и PF после команд ААА и AAS. Неясно, что должны обозначать флажки CF и AF после команд ААМ и AAD, поэтому они оставлены неопределенными.
Поскольку булевы операции никогда не дают результат вне диапазона, после их выполнения флажки OF и CF сбрасываются в 0. Флажок AF не имеет никакого отношения к булевым операциям (он предназначен только для десятичной арифметики), поэтому его состояние не определено. Флажки SF, ZF и PF отражают особенности результата операции.
Единственная булева операция NOT не воздействует на флажки. Это объясняется ошибкой при разработке микропроцессора 8086 и ради совместимости действие команды NOT оставлено таким же и в процессоре 80286.
Команды сдвига осуществляют умножение и деление на степень числа 2. Флажки состояния отражают особенности результата, но с двумя исключениями: значение флажка AF не определено (сдвиг не имеет к десятичной арифметике никакого отношения) и значение флажка OF не определено для переменных сдвигов (в этом случае механизм обнаружения переполнения довольно сложен). Команда арифметического сдвига вправо SAR никогда не дает знаковый результат вне диапазона, поэтому после ее выполнения флажок OF сбрасывается в 0.
Команды циклических сдвигов разработаны с учетом совместимости с аналогичными командами микропроцессора 8080 и аналогично воздействуют
на флажки. Состояние флажка CF зависит от результата, а состояния флажков OF, SF, ZF и PF не изменяются. Ради совместимости было решено, что команды циклических сдвигов должны воздействовать на флажок OF аналогично командам сдвигов, хотя и непонятно, что в этом случае обозначает переполнение.
Команды восстановления флажков возвращают в них ранее запомненные значения. В частности, команды POPF и IRET восстанавливают все флажки состояния и управления на значения, запомненные в стеке. Необычная команда SAHF (введенная только ради совместимости с микропроцессором 8080) передает во флажки состояния содержимое регистра АН.
Все прерывания сбрасывают флажки TF и IF в 0. Если не сбрасывать флажок TF, процессор и в отладчике работал бы в пошаговом режиме. Сброс флажка разрешения прерываний IF позволяет процедуре прерывания определить, следует ли разрешить обработку второго прерывания (для чего применяется команда STI).
Смысл команд, воздействующих на флажки CF, DF и IF, очевиден. Они устанавливают в 1, сбрасывают в 0 или инвертируют отдельный флажок и не влияют на состояние остальных флажков.
