Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Превышение предела сегмента

360
30 апреля 2008 года
P*t*
474 / / 15.02.2007
Я изучаю защищённый режим. Появилась проблема:

Не вызывается исключение GP при попытке записи за границей сегмента:

Такой код выполняю на 3-ем уровне привелегий при лимите сегмента данных 0x1ffff
 
Код:
char* a = (char*)0xffffff;
(*a) = 0;

По идее должно произойти исключение GP, но не происходит. Вместо него появляется PF - исключение неприсутствующей страницы.

Почему такое может быть?
у меня есть 2 варианта:
1) я чего-то не понял и так и должно быть.
2) ошибка в программе.

Уже 2 дня пытаюсь разобраться, но не получается.
Посоветуйте что-нибудь.
261
01 мая 2008 года
ahilles
1.5K / / 03.11.2005
чему равно поле G в дескрипторе сегмента данных?
360
01 мая 2008 года
P*t*
474 / / 15.02.2007
Дескрипторы создаю такой функцией:
Код:
void setLDTdescriptor(int process, int n, int base, unsigned int size, char acces) {
    int ldt = 0x50000 + process*0x100 + 0x80;
    (*(short*)(ldt+n*8+2)) = base%0x10000;
    (*(char*)(ldt+n*8+4)) = (base/0x10000)%0x100;
    (*(char*)(ldt+n*8+7)) = base/0x1000000;
    (*(char*)(ldt+n*8+5)) = acces;
    char b6 = 0x40;
    if (size>0x100000) {
        b6 |= 0x80;
        if (size%0x1000>0)
            size /= 0x1000 + 1;
        else
            size /= 0x1000;
    }
    b6|=size/0x10000;
    (*(char*)(ldt+n*8+6)) = b6;
    (*(unsigned short*)(ldt+n*8)) = size%0x10000;
}

По идее при size = 0xffff G должно быть равно нулю.
1.9K
04 мая 2008 года
disasm
232 / / 06.02.2006
Честно говоря мне больше нравится вот такой код. Если конечно это имеет значение.
Код:
void setLDTdescriptor(int process, int n, unsigned int base, unsigned int size, unsigned char acces) {
    unsigned int ldt = 0x50000 + process*0x100 + 0x80 + n*8;
    (*(unsigned short*)(ldt+2)) = base%0x10000;
    (*(unsigned char*)(ldt+4)) = (base/0x10000)%0x100;
    (*(unsigned char*)(ldt+7)) = base/0x1000000;
    (*(unsigned char*)(ldt+5)) = acces;
    unsigned char b6 = 0x40;
    if (size>=0x100000) {
        b6 |= 0x80;
        if (size%0x1000>0)
            size = size/0x1000 + 1;
        else
            size /= 0x1000;
    }
    b6|=size/0x10000;
    (*(unsigned char*)(ldt+6)) = b6;
    (*(unsigned short*)(ldt)) = size%0x10000;
}
360
04 мая 2008 года
P*t*
474 / / 15.02.2007
Свою программу тестирую в qemu . Сейчас попробовал записать на дискету и с неё загрузить комп - работает правильно.
Наверное это в qemu баг.

И ещё такая вещь - я думал память BIOSа только в первом мегабайте, но при попытки записать что-нибудь по некоторым адресам второго мегабайта компьютер перезагружается. Странно.


Цитата: disasm
Честно говоря мне больше нравится вот такой код. Если конечно это имеет значение.



Спасибо. При size=0x100000 это имеет значение.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог