Что произойдет, если самый старший бит указателя будет битом знака, может кто-нибудь привести пример, чтобы объяснить это? - PullRequest
0 голосов
/ 10 июля 2020

Я читаю книгу , в главе 13 - Windows Архитектура памяти - получение большего раздела пользовательского режима в x86 Windows

Я здесь :

В ранних версиях Windows Microsoft не разрешала приложениям получать доступ к их адресному пространству размером более 2 ГБ. Поэтому некоторые творческие разработчики решили использовать это, и в своем коде они будут использовать старший бит в указателе как флаг, имеющий значение только для их приложений. Затем, когда приложение обращалось к адресу памяти, выполнялся код, очищавший старший бит указателя перед использованием адреса памяти. Ну, как вы понимаете, когда приложение работает в среде пользовательского режима размером более 2 ГБ, приложение выходит из строя в огне.

Я не могу этого понять, может ли кто-нибудь сделать пример, чтобы объяснить это для меня, спасибо.

1 Ответ

0 голосов
/ 10 июля 2020

Для доступа к ~ 2 ГБ памяти вам нужен только 31-битный адрес. Однако в 32-битных системах адреса имеют длину 32 бита и, следовательно, указатели имеют длину 32 бита.

Как описано в книге, в ранних версиях windows разработчики могли использовать только 2 ГБ памяти, поэтому последний бит в каждом 32-битном указателе можно было использовать для других целей, так как он ВСЕГДА был нулевым. Однако перед использованием адреса этот дополнительный бит нужно было снова очистить, по-видимому, чтобы программа не взломала sh, потому что она пыталась получить доступ к адресу размером более 2 ГБ.

Код, вероятно, выглядел как-то вот так:

int val = 1;
int* p = &val;

// ...

// Using the last bit of p to set a flag, for some purpose
p |= 1UL << 31;

// ...

// Then before using the address in some way, the bit has to be cleared again:
p &= ~(1UL << 31);

*p = 3;

Теперь, если вы можете быть уверены, что ваши указатели будут указывать только на адрес, где старший бит (MSB) равен нулю, то есть в адресном пространстве ~ 2 ГБ, это хорошо. Однако, если адресное пространство увеличивается, некоторые указатели будут иметь 1 в своем старшем разряде, и, очистив его, вы установите указатель на неправильный адрес в памяти. Если вы затем попытаетесь читать или писать по этому адресу, у вас будет неопределенное поведение, и ваша программа, скорее всего, выйдет из строя в результате пожара .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...