Здравствуйте, Stanky, Вы писали:
S>S>The first entry of the GDT is not used by the processor. A segment selector that points to this
S>entry of the GDT (that is, a segment selector with an index of 0 and the TI flag set to 0) is used
S>as a “null segment selector.” The processor does not generate an exception when a segment
S>register (other than the CS or SS registers) is loaded with a null selector. It does, however,
S>generate an exception when a segment register holding a null selector is used to access memory.
S>A null selector can be used to initialize unused segment registers. Loading the CS or SS register
S>with a null segment selector causes a general-protection exception (#GP) to be generated.
S>
S>У фроловых написано примерно тоже самое, но мне непонятна практическая сторона сего действа
!!!
S>Зачем нам вообще инициализировать неиспользуемые регистры?
--
Ну, например, для того чтобы "отлавливать" действия с этим регистром, которые в таком случае будут являться некорректной работой с не инициализированным указателем. Чуть ниже по тексту (3.5.1) об этом прямо сказано "By initializing the segment registers with this [“null descriptor”] segment selector, accidental reference to unused segment registers can be guaranteed to generate an exception"
S>Если имеется ввиду, что это нужно при переходе из ядра в 3 кольцо, например обнулить FS и GS, то разве мы сами не можем это сделать, создав в таблице описание нулевого сегмента, если он нужен? Или он при загрузке такого селектора исключением срыгнёт? Да, я конечно умею читать: The processor does not generate an exception when a segment register (other than the CS or SS registers) is loaded with a null selector, но это читается не совсем однозначно!!!
--
Чтот такое "описание нулевого сегмента"? Вы хотите сделать сегмент в памяти и дескриптор для него, аналогичный тому, на который как будто-бы "ссылается" 0-й селектор GDT? Если да, то сделать это, по-моему, будет проблематично.
Во-первых, какой должен быть базовый адрес этого сегмента? С точки зрения “null descriptor”, сегмент, на который он "ссылается", должен быть недоступным или генерировать исключения при доступе к нему, а как это гарантировано сделать на всех (практических) платформах, использующих этот CPU?
Во-вторых, мы не можем сделать сегмент нулевой длины. Это значит, что любой сегмент имеет по крайней мере один валидный адрес в памяти. Опять же, этот не соответсвует работе с "null descriptor'ом".
Можно, конечно, все врямя маркировать дескриптор этого сегмента как "not present" (P бит = 0), но это, по достаточно явным причинам, нехорошо.
S>Вобщем для чего было вводить такую вещь аппаратно?
--
На мой взляд, все достаточно просто — этот механизм позволяет "отлавливать" ошибочные действия в программе, например, с указателями в C/C++:
— Запись NULL в переменную — это нормально (запись "null descriptor" в сегментые регистры, отличные от CS и SS, разрешен).
— Выполнять действия по адресу NULL — это ошибка (запись "null descriptor" в сегментые регистры CS и SS генерирует исключение);
— Запись и чтение по адресу NULL — это ошибка (обращение к памяти по сегментномуу регистру, содержащему "null descriptor", генерирует исключение);
С уважением,
Геннадий Майко.
P.S. Я считаю, что лучше самому прочесть "первоисточники", чем их цитировать. Только поэтому я не стал приводить как раз именно эту фразу, которые Вы сами нашли.