Loadall это общее название для двух различных недокументированных машинных инструкций от Intel 80286 и Intel 80386 процессоров, которые позволяют получать доступ к областям внутреннего состояния процессора, которые обычно вне IA-32 API сферы, как регистры кэша дескрипторов . LOADALL для 286 процессоров кодируется 0Fh 05h, [1], а LOADALL для 386 процессоров - 0Fh 07h. [2]
Оба варианта - как следует из названия - загружают все внутренние регистры процессора за одну операцию. LOADALL обладал уникальной способностью настраивать видимую часть сегментных регистров (селектор) независимо от их соответствующей кэшированной части, что позволяло программисту приводить ЦП в состояния, не допускаемые официальной моделью программирования.
В качестве примера полезности этих методов LOADALL может настроить ЦП, чтобы разрешить доступ ко всей памяти из реального режима , без необходимости переключать его в нереальный режим (который требует переключения в защищенный режим , доступа к памяти и, наконец, переключения обратно в реальный режим). Режим). Такие программы, как версии RAMDRIVE.SYS (1985) до XMS , [3] [1] [4] SMARTDRV.SYS (1986) [4], а также HIMEM.SYS (2.03, 1988-08-04; 2.04) , 1988-08-17) [4] драйверы в MS-DOS , Uniform Software Systems ' The Extender (1985) и The Connector (1985) для Lotus 1-2-3 , Above Disk (1986) [5] ( LIMulator от Above Software (ранее Tele-Ware West aka Los Angeles Securities Group ), который преобразовывал пространство на жестком диске или увеличивал память в расширенную ), а OS / 2 1.0 [3] [1] и 1.1 [6] использовали инструкцию 286 LOADALL. DOS 3.3 и 4.0 зарезервировали 102-байтовый буфер в 0070: 0100h (который обычно был занят DOS BIOSdata), чтобы не было необходимости сохранять и восстанавливать его для LOADALL. EMM386.EXE от Microsoft обрабатывает инструкции 286 и 386 LOADALL в своем обработчике недопустимого кода операции. [7] Изучение кода монитора виртуальной машины в Windows / 386 2.10 показывает, что он использует как 286 [ необходима цитата ], так и еще менее известный вариант 386 [ необходима цитата ] . Microsoft HIMEM.SYS версии 2.06 [8] также использовал LOADALL для быстрого копирования в расширенную память и из нее на 286 системах.
Еще одно интересное применение Loadall, изложенных в книге Дизайн OS / 2 , [9] было бы разрешить запуск прежних программ реального режима в защищенном режиме 16-битной, так как используются Digital Research «s Параллельная DOS 286 , так как 1985, [10] [11] [12], а также FlexOS 286 [13] и IBM 4680 OS [14] [15] с 1986 года. Маркировка всех кэшей дескрипторов в GDT и LDT«Отсутствует» позволит операционной системе перехватывать перезагрузку регистров сегмента, а также попытки выполнить специфичную для реального режима «арифметику сегментов» и имитировать желаемое поведение путем обновления дескрипторов сегментов (снова LOADALL). Однако этот «виртуальный режим 8086» для 80286 был слишком медленным, чтобы быть практичным. Более того, от этой идеи пришлось отказаться по большей части из-за ошибок в некоторых ранних процессорах Intel 80286 до степпинга E-2 . [10] [11] [13] В результате OS / 2 1.x, а также Windows в «стандартном» режиме должны были запускать программы DOS в реальном режиме. Тем не менее идея не была потеряна; это привело к тому, что Intel представила виртуальный режим 8086 в 80386, что позволило реализовать " блоки DOS""наконец-то относительно эффективным и задокументированным способом.
Поскольку LOADALL не выполнял никаких проверок достоверности данных, загруженных в регистры процессора, было возможно загрузить состояние процессора, которое нельзя было ввести обычным образом, например, использование реального режима (PE = 0) вместе с подкачкой (PG = 1 ) на процессорах класса 386. [2]
В цепи эмулятор (ICE) представляет собой инструмент , используемый для отладки низкого уровня. На Intel 80386 подтверждение недокументированного вывода в местоположении B6 заставляет микропроцессор останавливать выполнение и переходить в режим ICE. Микропроцессор сохраняет все свое состояние в области памяти, изолированной от нормальной системной памяти. Структура этой области подходит для инструкции LOADALL, и эта инструкция используется кодом ICE для возврата к нормальному выполнению.
В более поздних процессорах это превратилось в режим управления системой (SMM). В SMM инструкция RSM используется для загрузки полного состояния ЦП из области памяти. Структура этой области памяти аналогична структуре, используемой инструкцией LOADALL. [16] Команда LOADALL в стиле 386 также может выполняться на 486, но только в режиме SMM. В более поздних процессорах свою роль взяла на себя инструкция RSM с другой кодировкой.
Codeview 3.0 от Microsoft и Turbo Debugger 2.0 от Borland правильно декодируют инструкции LOADALL 286 и 386. [1]
Поскольку две инструкции LOADALL никогда не были документированы и не существуют в более поздних процессорах, коды операций были повторно использованы в архитектуре AMD64 . [17] Код операции для инструкции 286 LOADALL, 0F05, стал инструкцией AMD64 SYSCALL; инструкция 386 LOADALL, 0F07, стала инструкцией SYSRET. Эти определения были реализованы даже в процессорах Intel с введением Intel 64 реализации AMD64. [18]
Код операции 0F05. Инструкция считывает данные с адресов 00800–00866 независимо от содержимого сегментных регистров.
Адрес | количество байтов | регистр | регистр | регистр | регистр |
---|---|---|---|---|---|
00800 | 6 | не используется | |||
00806 | 2 | MSW, слово состояния машины | |||
00808 | 14 | не используется | |||
00816 | 2 | TR (реестр задач) | |||
00818 | 2 | флаги | |||
0081A | 2 | IP (указатель инструкции) | |||
0081C | 2 | LDTR, регистр таблицы локальных дескрипторов | |||
0081E | 4 × 2 | DS ( сегмент данных ) | SS (сегмент стека) | CS (сегмент кода) | ES (дополнительный сегмент) |
00826 | 4 × 2 | DI (индекс назначения) | SI (исходный указатель) | BP (базовый указатель) | SP (указатель стека) |
0082E | 4 × 2 | BX | DX | CX | ТОПОР |
00836 | 4 × 6 | Дескриптор сегмента ES | Дескриптор сегмента CS | Дескриптор сегмента SS | Дескриптор сегмента DS |
0084E | 4 × 6 | GDT, глобальная таблица дескрипторов | LDT, таблица локальных дескрипторов | IDT, таблица дескрипторов прерываний | TSS, сегмент состояния задачи |
Инструкцию 80286 LOADALL нельзя использовать для переключения из защищенного обратно в реальный режим [19] (она не может сбросить бит PE в MSW). Однако использование инструкции LOADALL может полностью избавить от необходимости переключаться в защищенный режим.
Код операции 0F07. Инструкция загружает данные с адреса ES: EDI. Фактически он использует ES, а не дескриптор ES.
Адрес | количество байтов | регистр | регистр | регистр | регистр |
---|---|---|---|---|---|
ES: EDI + 00 | 4 | CR0, регистр управления 0 | |||
ES: EDI + 04 | 4 | EFLAGS | |||
ES: EDI + 08 | 4 | EIP, указатель инструкции | |||
ES: EDI + 0C | 4 × 4 | EDI, индекс назначения | ESI, исходный указатель | EBP, базовый указатель | ESP, указатель стека |
ES: EDI + 1C | 4 × 4 | EBX | EDX | ECX | EAX |
ES: EDI + 2C | 2 × 4 | DR6 | DR7 | ||
ES: EDI + 34 | 4 | TR, селектор состояния задачи | |||
ES: EDI + 38 | 4 | LDTR, локальная таблица дескрипторов | |||
ES: EDI + 3C | 4 × 2 | GS, дополнительный сегмент | не используется | FS, дополнительный сегмент | не используется |
ES: EDI + 44 | 4 × 2 | DS, сегмент данных | не используется | SS, сегмент стека | не используется |
ES: EDI + 4C | 4 × 2 | CS, сегмент кода | не используется | ES, дополнительный сегмент | не используется |
ES: EDI + 54 | 4 × 12 | Дескриптор TSS, селектор состояния задачи | Дескриптор IDT, таблица дескрипторов прерываний | Дескриптор GDT, глобальная таблица дескрипторов | Дескриптор LDT, таблица локальных дескрипторов |
ES: EDI + 84 | 4 × 12 | Дескриптор сегмента GS | Дескриптор сегмента FS | Дескриптор сегмента DS | Дескриптор сегмента SS |
ES: EDI + B4 | 2 × 12 | Дескриптор сегмента CS | Дескриптор сегмента ES |