Вобщем то, в описаниях TSS все ясно как безоюлачный день, за исключением полей ESP0, SS0, ESP1, SS1, ESP2, SS2. Это чё? То, что эти поля имеют отношение к стеку - понятно. Но где и как они применяются? и для чего?
Поля используются для переключения стека с менее привелегированого кольца в более, например если обработчик прерывания выполнен на нолевом кольце и прерывание случилось при выполнении прикладной программы то процессор будет автоматически переключать стек и значения SS и ESP будет брать из TSS(SS0,ESP0). При этом также установит флаг NT, который влияет на выполнение команд возврата из прерывания.
Barbos У каждого из четырёх уровней привилегий есть свой собственный стек; соответствующие SS:ESP и хранятся в TSS. Фактически это единственное, из-за чего TSS нужна (аппаратная многозадачность умерла: в 64-разрядных процессорах от неё отказались, и единственный имеющийся там TSS как раз и используется для хранения четырёх указателей стека).
т.е. если для каждой из задач будут указаны свои уникальные адреса стеков, то каждая такая задача получает свой контекст обработки прерываний/исключений. Тут же мысль, не таким ли образом организован механизм обработки эксепшенов блоками try { } catch { }? А если задача работает в нулевом кольце и имеет свой стек, описанный в регистрах SS:ESP, то обязательно ли нужна настройка SS0:ESP0? что если там будут нули, произойдет ли нарушение защиты, если в момент выполнения этой задачи произойдет прерывание, обработчик которого находится тоже в нулевом кольце? И, если задача работает в нулевом кольце, имеют ли смысл значения полей SS1:ESP1, SS2:ESP2? Или ими можно пренебречь, инициировав их нулями и забыть о них? вопросов становится только больше
Нет, не таким способом. Если имеются в виду обычные эксцепшны. Не обязательно. Стек меняется только при повышении привилегий. Их можно не инициализировать, если работаешь только с кольцами 0 и 3 (как все обычно и делают).
вот теперь я понял почему их там три набора, в то время как колец всего 4. Тогда получается, что (для эксперимента) для организации работы двух простых задач, работающих в ring0, можно вобще не трогать SSx:ESPx, даже не смотря на то, что в системе присутствуют обработчики аппаратных прерываний, конфликтов в ними происходить не должно.
Barbos Их там четыре. Считайте: SS0:ESP0 по смещению 4, SS1:ESP1 по смещени 12, SS2:ESP2 по смещению 20 и SS:ESP по смещениям 56 и 80.
Barbos SadKo У меня как-то из-за неинициализированности TSS после переключения в защищёнку возникала двойная ошибка, хотя логически её быть не должно. Я вручную грузил SS:ESP, находясь в нулевом кольце, и именно при загрузке SS происходил вылет. После инициализации TSS глюк исчез сам по себе (загружаемые значения не менял). Так что не уверен, что "не обязательно" (хотя, возможно, процессору просто требовалось наличие TSS, а какая там пурга находится -- без разницы, пока нет переключения привилегий). Вот это точно.
это значения, которые были в SS:ESP в момент переключения задач они не связаны с DPL (в отличие от первых 3-х пар)
Не стал трогать SSx:ESPx вобще. Две задачи, обе в нулевом кольце, по инициативе с клавы, одна запускает другую и получает управление, когда та отработает. Все нормально работает. Спасибо.
Здесь все понятно, но как передать управление другой задаче и сохканить ее контекст. Ведь аппаратное переключение не поддерживается в x64???
x64 поддерживает аппаратное переключения задач, просто от него отказываются для экономии памяти или что то около того
Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A: 6.7 TASK MANAGEMENT IN 64-BIT MODE там,если смотреть дальше по тексту, пишут, что при передаче управления на TSS или шлюз TSS (JMP, CALL, INTn, or interrupt) происходит #GP. т.е само собой напрашивается вешать кусок кода на 13-й вектор в IDT. В коде определять по коду ошибки причину, ну и т.д. примерно как монитор V86... тем более, что An IRET with EFLAGS.NT (nested task) set to 1 тоже вызывает #GP, обычное обратное переключение задач.