Переключение задачи
Переключение задачи в x86 могут вызвать следующие четыре события: □ старая задача выполняет команду far call или far jmp, и селектор выбирает шлюз задачи □ старая задача выполняет команду far call или far jmp, и селектор выбирает дескриптор TSS; □ старая задача выполняет команду iret для возврата в предыдущую задачу; эта команда приводит к переключению задачи, если в регистре EFLAGS бит вложенной задачи NT=1; □ возникло аппаратное или программное прерывание и соответствующий элемент дескрипторной таблицы прерываний IDT содержит шлюз задачи. Под термином "старая задача" ("выходящая задача") будем понимать ту задачу, выполнение которой прекращается; под термином "новая задача" ("входящая задача") будем понимать ту задачу, которую начинает выполнять процессор. (Страница196) Таким образом, селекторами в командах переходов и вызовов могут быть как селекторы TSS (прямое переключение задачи), так и селекторы шлюзов задачи (косвенное переключение задачи). В последнем случае дескриптор шлюза задачи обязательно содержит селектор TSS. Формат дескриптора шлюза задачи приведен на рис. 7.12. Рис. 7.12. Форматы шлюза задачи и дескриптора TSS Старая задача должна быть достаточно привилегированна для доступа к шлюзу задачи или к сегменту TSS. Правила привилегий обычные: □ max(CPL, RPL)>DPL шлюза задачи: □ max(CPL, RPL)>DPL сегмента TSS. Процедура возврата из прерываний IRET всегда возвращает управление прерванной программе. Если флаг NT сброшен в 0, производится обычный возврат, а если он установлен в 1 — происходит переключение задачи. При этом процессор сохраняет свое состояние в сегменте TSS старой задачи, загружает в регистр TR содержимое поля обратной связи — селектор новой задачи ("задачи-предка", т. к. осуществляется возврат) и восстанавливает из сегмента TSS контекст новой задачи. Благодаря наличию в каждом сегменте TSS поля обратной связи можно поддерживать многократные вложения задач. Характерно, что команда возврата из подпрограммы ret не чувствительна к значению флага NT и не может осуществить переключение задачи. После модификации TR и загрузки нового контекста из сегмента TSS процессор отмечает этот сегмент как занятый (устанавливает бит 41 занятости Busy в его дескрипторе). Занятый TSS может относиться либо к выполняющейся, либо ко вложенной задаче. Переключение на задачу, отмеченную как занятая, не производится! В частности, это исключает возможность реализации реентерабельных задач. Исключение представляет только команда iret, которая возвращает управление задаче-предку (очевидно, будучи вложенной, она отмечена как запятая). При переключении задачи процессор устанавливает также флаг переключения задачи TS в регистре CR0. Сброс этого флага может осуществиться только привилегированной командой clts. TS применяется для правильного использования некоторых системных ресурсов, в частности — устройства плавающей арифметики (Float Point Unit, FPU). Если при каждом переключении задачи сохранять состояние FPU, то на это уйдет много времени, причем новая задача может вообще не использовать ресурсы FPU, и тогда такое сохранение окажется напрасным. В процессоре 80486 команды FPU анализируют состояние флага TS и если TS=1, формируется особый случай 7 и вызывается системная процедура сохранения состояния FPU. После этого флаг TS сбрасывается. При переключении задачи процессор не фиксирует факт использования новой задачей FPU. Очевидно, это забота обработчика прерывания 7 — сам обработчик или ОС может поддерживать в TSS флаг использования сопроцессора. Кроме того, обработчик прерывания 7 может запоминать селектор TSS последней программы, использующей FPU. Итак, процесс переключения задачи можно представить следующим образом. Имеется TR с теневым регистром дескриптора TSS, определяющий TSS старой задачи. Если селектор в командах far jmp, far call, iret (NT=1), int указывает прямо (дескриптор TSS) или косвенно (шлюз задачи) в GDT на системный объект переключения задачи, то производится переключение задачи: □ процессор сохраняет контекст старой задачи в сегменте TSS старой задачи; □ процессор загружает в TR селектор сегмента новой задачи; □ процессор загружает в сегмент TSS новой задачи селектор TSS старой задачи (в поле обратной связи); □ получив доступ к сегменту TSS новой задачи, процессор загружает контекст новой задачи в регистры (в том числе CS: EIP — точка старта); □ процессор устанавливает флаги NT (в регистре EFLAGS) и TS (в CR0 для анализа командами FPU), устанавливает бит занятости задачи в дескрипторе TSS новой задачи.
|