9. Эмуляция 8086    
 СОДЕРЖАНИЕ
 Введение
 1. Развитие архитектуры
 2. Структура МП
 3. Ресурсы МП
 4. Управление памятью
 5. Защита
 6. Многозадачность
 7. Прерывания и исключения
 8. Инициализация МП
 9. Эмуляция 8086
 Глоссарий
 ПРАКТИКА
 1. Семантический разрыв
 2. CPUID
 3. Защищенный режим
 Вопросы и задания

9.1 Реальный режим

Среда выполнения в реальном режиме копирует среду выполнения МП 8086/88. Для программы МП 8086/88 современный микропроцессор в реальном режиме ведет себя как высокоскоростной МП 8086.

Для среды выполнения в реальном режиме характерны следующие особенности:

  1. Процессор поддерживает адресное пространство до 1Мбайт, организованное как "модель режима реального адреса". Адресное пространство разбито на сегменты по 64Кбайт. 20-битный базовый адрес сегмента вычисляется сдвигом значения селектора на 4 бита влево. Данные внутри сегмента адресуются 16-битным смещением.
    Формирование адреса в RM

    В этом режиме формирования линейного адреса есть возможность адресовать пространство между 1Мб и 1Мб+64Кб (например, указав в качестве селектора 0FFFFh, а в качестве смещения 0FFFFh, мы получим линейный адрес 10FFEFh). Однако МП 8086, обладая 20-разрядной шиной адреса, отбрасывает старший бит, "заворачивая" адресное пространство (в данном примере МП 8086 обратится по адресу 0FFEFh). В реальном режиме микропроцессоры IA-32 "заворачивания" не производят. Для 486+ появился новый сигнал - A20M#, который позволяет блокировать 20-й разряд шины адреса, эмулируя таким образом "заворачивание" адресного пространство, аналогичное МП 8086.

    Хотя в программах для реального режима можно использовать префикс смены размера адреса, смещение в любом случае не должно выходить за 0FFFFh (предел сегментов в реальном режиме), в противном случае генерируется исключение #13 (или #12 для стека).

  2. В реальном режиме поддерживаются все регистры общего назначения и сегментные регистры МП 8086. Команды оперируют с 8-битными и 16-битными регистрами. Кроме того, программам доступны новые сегментные регистры FS и GS. Более того, используя префикс смены размера операнда, программа может использовать 32-битные операнды и все 32 разряда регистров общего назначения.
  3. Программа работает с единым 16-битным стеком, на который указывает регистр SS. Регистр SP содержит 16-битное смещение вершины стека. Для адресации внутри стека можно также использовать регистр BP. При выполнении вызова (CALL) процессор помещает младшие 16 бит регистра EIP в стек (а при выполнении межсегментного вызова - также значение CS). При возврате по инструкции RET процессор извлекает из стека адрес следующей команды (и значение CS - при межсегментном возврате). При вызове обработчика прерывания или исключения процессор помещает в стек младшие 16 бит регистра EIP, значение CS и младшие 16 бит регистра флагов EFLAGS. При возврате из обработчика по инструкции IRET процессор извлекает из стека эти значения.
  4. Адреса обработчиков прерываний и исключений хранятся в таблице векторов прерываний. Номер прерывания или исключения является индексом для этой таблицы, а ее элементы - вектора прерываний (4 байта) - представляют собой 16-битные селекторы и 16-битные смещения точек входа в процедуры обработчиков.
    Таблица векторов прерываний

    Базовый адрес таблицы векторов прерываний хранится в специальном регистре IDTR и может быть изменен с помощью инструкции LIDT, в отличие от МП 8086, у которого таблица векторов прерываний всегда располагается по адресу 00000h. При вызове обработчика микропроцессор очищает флаги TF, RF и IF. В реальном режиме исключения процессора не генерируют код ошибки и не включают его в стек. МП 8086 генерирует лишь исключения #0, #2, #3 и #4, а остальные микропроцессоры IA-32 генерируют исключения #0-#8, #12 и #13 (при превышении пределов сегментов), #16 и #18 (Pentium+).

  5. В реальном режиме микропроцессоры IA-32 поддерживают все инструкции МП 8086/186/286, но кроме них программа может использовать также новые инструкции:
    • инструкции работы с управляющими регистрами и регистрами отладки (MOV to/from CRx, DRx);
    • инструкции загрузки сегментных регистров LSS, LFS, LGS;
    • инструкции загрузки со знаковым расширением (MOVSX, MOVZX);
    • инструкции условных переходов с 16-битным смещением;
    • инструкции обмена CMPXCHG (486+), CMPXCHG8B (Pentium+), XADD (486+);
    • инструкции тестирования и сканирования битов BT, BTS, BTR, BTC, BSF, BSR;
    • инструкции обмена байтами BSWAP (486+);
    • инструкции проверки условия SETcc;
    • инструкции двойного сдвига SHLD, SHRD;
    • инструкцию идентификации процессора CPUID;
    • системные инструкции CLTS, LGDT, SGDT, LIDT, SIDT, LMSW, SMSW;
    • инструкции управления кэшем (486+) INVD, WINVD, INVLPG;
    • инструкции для работы со специальными регистрами RDMSR (Pentium+), WRMSR (Pentium+), RDTSC (Pentium+), RDPMC (P6+).

    При попытке выполнить другие инструкции микропроцессоров IA-32 будет генерироваться исключение #6.