Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Глава II нарушение границ
Поле " Лимит" дескриптора сегмента призвано уберечь программы (процедуры) от незаконного обращения к памяти за пределами, установленными этим полем. Эффективное (реальное) значение лимита зависит от флага гранулярности G. Для сегментов данных, лимит также зависит от флага E (направление роста) и флага B дескриптора. Влияние бита G на поле " Лимит" изучено и рассмотрено со всех сторон в предыдущих выпусках, но напомню: если бит G=0, то лимит сегмента совпадает со значением одноименного поля дескриптора; очевидно, что в данном случае сегмент может иметь длину от 0 до FFFFFh (1Мб). Если флаг G=1, то реальный лимит сегмента равен содержимому поля " Лимит" дескриптора, умноженному на 4Кб (FFFh). Очевидно, сегмент в этом случае может занимать от 4Кб до 4Гб. ВАЖНО! Если бит G=1, то младшие 12 бит адреса НЕ ПРОВЕРЯЮТСЯ НА ПРЕВЫШЕНИЕ ЛИМИТА! Т.е. если создать дескриптор сегмента с G=1, и полем " Лимит" равным 0, то смещения от 0 до FFFh ВСЕ РАВНО ДОСТУПНЫ ДЛЯ ОБРАЩЕНИЯ! Т.е. процессор ИГНОРИРУЕТ младшие 12 бит при проверке на превышение лимита. Вообще, как где-то было верно подмечено, бит гранулярности - это чисто радиолюбительский трюк. Что еще небезынтересно знать - умножение на 4Кб равносильно сдвигу на 12 влево, причем младшие 12 бит при этом заполняются единицами. Итак, процессор сгенерирует исключение #GP (самое страшное и главное, недаром ему присвоили 13 номер) в следующих случаях:
Это 4 заповеди данной главы. Существует еще один размытый момент, который мы сейчас обсудим во всех нюансах. Этот момент - растущие " ВНИЗ" сегменты данных. Тут сразу нужно сказать - сегмент никуда не растет, это образное выражение. Все дело в том, что у растущих " ВНИЗ" сегментов поле " Лимит" в дескрипторе определяет НИЖНЮЮ границу сегмента, а ВЕРХНЯЯ граница ВСЕГДА (!) (подчеркнуть три раза) равна FFFFh (1Мб) если бит B=0 и FFFFFFFFh (4Гб) если бит B=1. Откуда взялся бит B? Вспоминаем структуру дескриптора, помните флаг D/B? Вот это он и есть. Теперь у некоторых возникает вопрос: если у нас определена НИЖНЯЯ граница сегмента (поле " Лимит") и верхняя (1Мб или 4Гб), то нахрена тогда поле БАЗА в дескрипторе? Спокойно! Стоит лишь чуть-чуть подумать и все станет ясно: поле " Лимит" хоть и определяет нижнюю границу, но все равно ОТСЧИТЫВАЕТСЯ ОТ БАЗЫ! Т.е. фактически нижняя граница у растущих ВНИЗ сегментов равна: содержимое поля " Лимит" дескриптора + содержимое поля " База" дескриптора. Вот для того нам база и нужна... (вообще с тем что поле " Лимит" всегда зависит от поля " База" интеловцы imho погорячились, т.к. весь этот механизм в конечном счете выгоден только при использовании 36-разрядного механизма адресации PAE-36. У кого есть какие-нибудь соображения на этот счет - прошу поделиться). Здесь интересен другой момент (подумайте и вышлите свои соображения на brokensword@mail.ru): если у нас есть растущий ВНИЗ сегмент, у которого сброшен бит B, т.е. верхняя граница этого сегмента равна FFFFh, а поле " База" в дескрипторе ПРЕВЫШАЕТ значение 1Мб. Кто может ответить - какие смещения доступны в таком сегменте? Наконец, позволю себе привести фрагмент из книги тов. Зубкова С.В. по поводу растущих вниз сегментов: " Бит направления роста сегмента (E) обращает смысл лимита сегмента. В сегментах с этим битом, сброшенным в ноль, разрешены абсолютно все смещения от 0 до лимита, а если этот бит 1, то допустимы все смещения, кроме от 0 до лимита. Про такой сегмент говорят, что он растет сверху вниз, так как если лимит, например, равен -100, допустимы смещения от -100 до 0, а если лимит увеличить, станут допустимыми еще меньшие смещения". Здесь уважаемый Зубков запорол страшную ерунду, т.к., во-первых, не " от 0 до лимита", а от " (базы) до (база+лимит)", и в случае растущих вниз сегментов, помимо той же самой ошибки, он рассмотрел только случай когда B=1 (т.е. верхняя граница равна 4Гб), тогда действительно доступны ВСЕ смещения, кроме от база+лимит до 0 (" вниз"). Да и с примером он тоже намудрил. Если кто-то не согласен - пишите, обсудим. Еще раз нелишне повторить, что суть проверок лимитов заключается в том, чтобы не дать программам разгуляться по всей памяти, каждый сверчок должен знать свой шесток и не вылазить за отведенные ему границы. Данная глава была бы не полной, если не вспомнить о том, что процессор (помимо проверки лимитов сегментов) проверяет также лимиты таблиц дескрипторов, инфа о которых содержится в регистрах GDTR, IDTR, LDTR и TR. #GP будет сгенерировано, если произойдет попытка обращения к дескриптору, лежащему за пределами таблицы дескрипторов. Вот теперь по теме " Проверка границ" больше добавить действительно нечего. В следующем выпуске мы рассмотрим следующую главу УК IA-32 под названием " Проверка типов".
|