-----------------------------------------------------------------|Код Команда Число Описание ||операции тактовых || циклов ||E8 cw CALL rel16 3 Вызов ближний, смещение отно- || сительно следующей команды ||FF /2 CALL r/m16 5/5 Вызов ближний, косвенный ре- || гистр/косвенная память ||9A cd CALL ptr16:16 18,pm=20 Вызов межсегментный, на весь || заданный указатель ||9A cd CALL ptr16:16 pm=35 Вызов шлюзом, та же привилеги-|| рованность ||9A cd CALL ptr16:16 pm=69 Вызов шлюзом, большая привиле-|| гированность, без параметров ||9A cd CALL ptr16:16 pm=77+4x Вызов шлюзом, большая привиле-|| гированность, х параметров ||9A cd CALL ptr16:16 pm=37+ts Вызов задачи || ||FF /3 CALL m16:16 17,pm=20 Вызов межсегментный, адрес в || двойном слове r/m ||FF /3 CALL m16:16 pm=35 Вызов шлюзом, та же привилеги-|| рованность ||FF /3 CALL m16:16 pm=69 Вызов шлюзом, большая привиле-|| гированность, без параметров ||FF /3 CALL m16:16 pm=77+4x Вызов шлюзом, большая привиле-|| гированность, х параметров ||FF /3 CALL m16:16 pm=37+ts Вызов задачи || ||E8 cd CALL rel32 3 Вызов ближний, смещение отно- || сительно следующей команды ||FF /2 CALL r/m32 5/5 Вызов ближний, косвенный || ||9A cp CALL ptr16:32 18,pm=20 Вызов межсегментный, на весь || заданный указатель ||9A cp CALL ptr16:32 pm=35 Вызов шлюзом, та же привилеги-|| рованность ||9A cp CALL ptr16:32 pm=69 Вызов шлюзом, большая привиле-|| гированность, без параметров ||9A cp CALL ptr32:32 pm=77+4x Вызов шлюзом, большая привиле-|| гированность, х параметров ||9A cp CALL ptr16:32 pm=37+ts Вызов задачи || ||FF /3 CALL m16:32 17,pm=20 Вызов межсегментный, адрес в || двойном слове в r/m ||FF /3 CALL m16:32 pm=35 Вызов шлюзом, та же привиле- || гированность ||FF /3 CALL m16:32 pm=69 Вызов шлюзом, большая привиле-|| гированность, без параметров ||FF /3 CALL m16:32 pm=77+4x Вызов шлюзом, большая привиле-|| гированность, х параметров ||FF /3 CALL m16:32 pm=37+ts Вызов задачи |----------------------------------------------------------------- Примечание: значения ts задаются следующей таблицей: ----------------------------------------------------------------- | Новая задача Старая задача |------------------------------------------- | к TSS i486 | к TSS 80286 | к TSS VM----------------------------------------------------------------- VM/i486/TSS 80286 | 199 | 180 | 177----------------------------------------------------------------- Работа команды IF тип вызова rel16 или rel32THEN (* ближний относительный вызов *) IF OperandSize = 16 THEN Push(IP); EIP <- (EIP + rel16) AND 0000FFFFH; ELSE (* OperandSize = 32 *) Push(EIP); EIP <- EIP + rel32; FI;FI; IF тип вызова r/m16 или r/m32THEN (* ближний абсолютный вызов *) IF OperandSize = 16 THEN Push(IP); EIP <- [r/m16] AND 0000FFFFH; ELSE (* OperandSize = 32 *) Push(EIP); EIP <- [r/m32]; FI;FI; IF (PE = 0 OR (PE = 1 AND VM = 1))(* режим реальных адресов или виртуальный режим 8086 *) AND команда = дальний CALL (* т.е. тип операнда равен m16:16, m16:32, ptr16:16, ptr16:32 *)THEN IF OperandSize = 16 THEN Push(CS); Push(IP); (* адрес следующей команды; 16 битов *) ELSE Push(CS); (* 16 старших битов занято заполнителями *) Push(EIP); (* адрес следующей команды; 32 бита *) FI; IF тип операнда равен m16:16 или m16:32 THEN (* косвенный дальний вызов *) IF OperandSize = 16 THEN CS:IP <- [m16:16]; EIP <- EIP AND 0000FFFFH; (* очистить старшие 16 битов *) ELSE (* OperandSize = 32 *) CS:IEP <- [m16:32]; FI; FI; IF тип операнда равен ptr16:16 или ptr16:32 THEN (* прямой дальний вызов *) If OperandSize =16 *) THEN CS:IP <- ptr16:16; EIP <- EIP AND 0000FFFFH; (* очистить старшие 16 битов *) ELSE (* OperandSize = 32 *) CS:EIP <- ptr16:32; FI; FI;FI; IF (PE = 1 AND VM = 0) (* Защищенный режим, но не режим V86 *) AND команда = дальний CALLTHEN При косвенном проверить доступ к двойному слову EA; #GP(0) при нарушении границы; Новый селектор CS не должен быть пустым, иначе #GP(0); Проверить, чтобы индекс селектора нового CS был в пределах границ дескрипторной таблицы; иначе #GP(селектор нового CS) Исследовать различные допустимые значения байта AR выбранного дескриптора; В зависимости от значения; переход к КОНФОРМНЫЙ-КОДОВЫЙ-СЕГМЕНТ; переход к НЕКОНФОРМНЫЙ-КОДОВЫЙ-СЕГМЕНТ; переход к ШЛЮЗ-ВЫЗОВА; переход к ШЛЮЗ-ЗАДАЧИ; переход к СЕГМЕНТ-СОСТОЯНИЯ-ЗАДАЧИ; ELSE #GP(селектор кодового сегмента);FI; КОНФОРМНЫЙ-КОДОВЫЙ-СЕГМЕНТ: DPL должен быть <= CPL ELSE #GP(селектор кодового сегмента); Сегмент должен присутствовать ELSE #NP (селектор кодового сегмента); Стек должен быть достаточно велик для адреса возврата ELSE #SS(0); Указатель команд должен быть в границах кодового сегмента ELSE #GP(0); Загрузить дескриптор кодового сегмента в регистр CS; Загрузить в CS селектор нового кодового сегмента; Загрузить в EIP с расширенем нулем (новое смещение); IF OperandSize = 16 THEN EIP <- EIP AND 0000FFFFH; FI; НЕКОНФОРМНЫЙ-КОДОВЫЙ-СЕГМЕНТ: RPL должен быть <= CPL ELSE #GP(селектор кодового сегмента); DPL должен быть = CPL ELSE #GP(селектор кодового сегмента); Сегмент должен присутствовать ELSE #NP (селектор кодового сегмента); Стек должен быть достаточно велик для адреса возврата ELSE #SS(0); Указатель команд должен быть в границах кодового сегмента ELSE #GP(0); Загрузить дескриптор кодового сегмента в регистр CS; Загрузить в CS селектор нового кодового сегмента; Установить RPL для CS равным CPL; Загрузить в EIP с расширенем нулем (новое смещение); IF OperandSize = 16 THEN EIP <- EIP AND 0000FFFFH; FI; ШЛЮЗ-ВЫЗОВА: DPL шлюза вызова должен быть >= CPL ELSE #GP(селектор шлюза вызова); DPL шлюза вызова должен быть >= RPL ELSE #GP(селектор шлюза вызова); Шлюз вызова должен присутствовать ELSE #NP(селектор шлюза вызова); Рассмотрим селектор кодового сегмента в дескрипторе шлюза вызова: Селектор не должен быть пустым ELSE #GP(0) Селектор должен быть в пределах границ его дескрипторной таблицы ELSE #GP(селектор кодового сегмента) Байт AR выбранного дескриптора должен обозначать кодовый сегмент ELSE #GP (селектор кодового сегмента) DPL выбранного дескриптора должен быть <= CPL ELSE #GP(селектор кодового сегмента) IF неконформный кодовый сегмент AND DPL <CPL THEN переход к БОЛЬШАЯ-ПРИВИЛЕГИРОВАННОСТЬ ELSE переход к ТА-ЖЕ-ПРИВИЛЕГИРОВАННОСТЬ FI; БОЛЬШАЯ-ПРИВИЛЕГИРОВАННОСТЬ: Взять селектор нового SS для нового уровня привилегированность в TSS Проверить селектор и дескриптор для нового SS: Селектор не должен быть пустым ELSE #TS(0) Индекс селектора должен находиться в пределах границ его дескрипторной таблицы ELSE #TS(селектор SS) RPL селектора должен быть равен DPL кодового сегмента ELSE #TS(селектор SS) Дескриптор должен указывать на сегмент данных, доступный для записи ELSE #TS(селектор SS) Сегмент присутствует ELSE #SS(селектор SS) IF OperandSize = 32 THEN Новый стек должен иметь место для параметров, плюс 16 байт ELSE #SS(селектор сегмента) EIP должен быть в границе кодового сегмента ELSE #GP(0) Загрузить новое значение SS:eSP из TSS Загрузить новое значение CS:EIP из шлюза ELSE Новый стек должен иметь место для параметров, плюс 8 байт ELSE #SS(селектор SS) IP должен быть в границах кодового сегмента ELSE #GP(0) Загрузить новое значение SS:eSP из TSS Загрузить новое значение CS:IP из шлюза FI; Загрузить дескриптор CS Загрузить дескриптор SS Поместить дальний указатель старого стека в новый стек Взять слово счетчика из шлюза вызова, маскировать 5 битов Скопировать параметры из старого стека в новый Поместить в новый стек адрес возврата Установить CPL равным DPL стекового сегмента Установить RPL для CS равным CPL ТА-ЖЕ-ПРИВИЛЕГИРОВАННОСТЬ: IF OperandSize = 32 THEN Стек должен иметь место для 6-байтового адреса возврата (до 8 байтов дополненного заполнителями) ELSE #SS(0) EIP должен быть в пределах границы кодового сегмента ELSE #GP(0) Загрузить CS:EIP из шлюза ELSE Стек должен иметь место для 4-байтового адреса возврата ELSE #SS(0) IP должен быть в пределах границы кодового сегмента ELSE #GP(0) Загрузить CS:IP из шлюза Поместить в стек адрес возврата Загрузить дескриптор кодового сегмента в регистр CS Установить RPL для CS равным CPL ШЛЮЗ-ЗАДАЧИ: DPL шлюза задачи должен быть >= CPL ELSE #TS(селектор шлюза) DPL шлюза задачи должен быть >= RPL ELSE #TS(селектор шлюза) Шлюз задачи должен присутствовать ELSE #NP(селектор шлюза) Исследовать селектор TSS, заданный в дескрипторе шлюза задачи: Он должен задавать бит Глобальный/Локальный как Глобальный ELSE #TS(селектор TSS) Индекс должен находиться в пределах границы GDT ELSE #TS(селектор TSS) Байт AR дескриптора TSS должен задавать неЗанятый TSS ELSE #TS(селектор TSS) Сегмент состояния задачи (TSS) должен присутствовать ELSE #NP(селектор TSS) ПЕРЕКЛЮЧЕНИЕ-ЗАДАЧ (со вложенностью) на TSS IP должен находиться в границе кодового сегмента ELSE #TS(0) СЕГМЕНТ-СОСТОЯНИЯ-ЗАДАЧИ: DPL для TSS должен быть >= CPL ELSE #TS(селектор TSS) DPL для TSS должен быть >= RPL ELSE #TS(селектор TSS) Байт AR дескриптора TSS должен задавать доступный TSS ELSE #TS(селектор TSS) Сегмент состояния задачи (TSS) должен присутствовать ELSE #NP(селектор TSS) ПЕРЕКЛЮЧЕНИЕ-ЗАДАЧ (со вложенностью) на TSS IP должен находиться в границе кодового сегмента ELSE #TS(0) ОписаниеКоманда CALL вызывает выполнение процедуры, указанной в операнде. Призавершении процедуры (команда возврата выполняется вызванной процедурой)выполнение продолжается с команды, следующей за командой CALL. Ниже описано действие для различных форм команды.Ближними называются вызовы с назначениями типа r/m16, r/m32, rel16, rel32;изменение или сохранение значения сегментного регистра не требуется. Формыкоманды CALL rel16 и CALL rel32 складывают имеющее знак смещение адресакоманды, следующей за командой CALL, для определения назначения. Формаrel16 используется, когда атрибут размера операнда команды равен 16 битам;форма rel32 используется при значении этого атрибута, равном 32 битам.Результат записывается в 32-битовый регистр EIP. В случае rel16 старшие 16битов регистра EIP очищаются , что дает значение смещение, не превышающее16 битов. Команды CALL r/ m16 и CALL r/m32 задают регистр или адреспамяти, из которого выполняется выборка абсолютного смещения сегмента.Смещение, выбранное из r/m, равно 32 битам для атрибута размера операнда32 (r/m32), или 16 битам для атрибута размера операнда 16 (r/m16).Смещение для команды, следующей за командой CALL, помещается в стек. Онабудет снята из стека ближней командой RET в пределах вызванной процедуры.Регистр CS этой формой команды CALL не изменяется. Дальние вызовы, CALL ptr16:16 и CALL ptr16:32, используют в качестведальнего указателя на вызываемую процедуру четырех- или шести-байтовыйоперанд. Формы CALL m16:16 и m16:32 извлекают дальний указатель иззаданного адреса памяти (косвенная ссылка). В режиме реальных адресов иливиртуальном режиме 8086 дальние указатели содержат 16 битов для регистраCS и 16 или 32 бита для регистра EIP (в зависимости от атрибута размераоперанда). Эти формы команды помещают в стек оба регистра, IP и EIP, вкачестве адреса возврата.В защищенном режиме обе формы дальних указателей обращаются к байту AR вдескрипторе, индексируемом селекторной частью дальнего указателя. Взависимости от значения байта AR вызов выполнит один из следующих типовпередачи управления: - Дальний вызов к тому же самому уровню защиты- Дальний вызов между разными уровнями защиты- Переключение задачиБолее подробную информацию о передаче управления в защищенном режиме см. вглавах 6 и 7. Изменяемые флагиПри переключении задачи изменяются все флаги; если же переключение задачине происходит, то флаги не изменяются. Исключения защищенного режимаДля дальних вызовов: #GP, #NP, #SS и #TS, как указано в разделе "Работакоманды".Для ближних прямых вызовов: #GP(0), если процедура находится за пределамиграницы кодового сегмента; #SS(0) в случае недопустимого адреса в сегментеSS; #PF(код сбоя) в случае страничного сбоя; #AC для невыравненной ссылкик памяти при текущем уровне привилегированности, равном 3. Исключения режима реальных адресовПрерывание 13, если какая-либо часть операнда лежит вне пространстваисполнительных адресов от 0 до 0FFFFH. Исключения виртуального режима 8086Те же исключения, что и для режима реальных адресов: #PF (код сбоя) длястраничных сбоев; #AC для невыравненной ссылки к памяти при текущем уровнепривилегированности, равном 3. ПримечанияЛюбой дальний вызов из 32-разрядного кодового сегмента в 16-разрядныйкодовый сегмент должен находиться в первых 64К 32-разрядного кодовогосегмента, поскольку атрибут размера операнда команды в этом случаеустанавливается на 16, что позволяет сохранить только 16-битовое смещениеадреса возврата.