char* a = (char*)0xffffff;
(*a) = 0;
Превышение предела сегмента
Не вызывается исключение GP при попытке записи за границей сегмента:
Такой код выполняю на 3-ем уровне привелегий при лимите сегмента данных 0x1ffff
Код:
По идее должно произойти исключение GP, но не происходит. Вместо него появляется PF - исключение неприсутствующей страницы.
Почему такое может быть?
у меня есть 2 варианта:
1) я чего-то не понял и так и должно быть.
2) ошибка в программе.
Уже 2 дня пытаюсь разобраться, но не получается.
Посоветуйте что-нибудь.
чему равно поле G в дескрипторе сегмента данных?
Код:
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;
}
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 должно быть равно нулю.
Код:
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;
}
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;
}
Наверное это в qemu баг.
И ещё такая вещь - я думал память BIOSа только в первом мегабайте, но при попытки записать что-нибудь по некоторым адресам второго мегабайта компьютер перезагружается. Странно.
Цитата: disasm
Честно говоря мне больше нравится вот такой код. Если конечно это имеет значение.
Спасибо. При size=0x100000 это имеет значение.