Является ли адрес глобальных переменных одинаковым для разных прогонов программы?

Рассмотрим следующий фрагмент кода

int i=10;
int main()
{
cout<<&i;
}

После того, как для программы будет сгенерирован exe, будет ли вывод одинаковым для разных запусков программы? Предположим, что ОС поддерживает виртуальную память

Редактировать: задание относится к глобальным переменным, которые хранятся в сегменте данных. Поскольку это первая глобальная переменная, должен ли адрес быть одинаковым или другим?

3

Решение

Вы всегда получаете одинаковые адреса, если ASLR выключен. Вы получите непредсказуемые адреса, если ASLR включен.

1

Другие решения

виртуальный адрес будет тем, что решил компоновщик. физическое адрес будет меняться с каждой загрузкой.

3

Простой ответ: это зависит 🙂

Если ваша ОС запускается для программы всегда в той же среде с диапазоном виртуальной памяти, который выглядит всегда одинаково, выходные данные должны быть всегда одинаковыми.

Но если вы запускаете одну и ту же операционную систему на другом оборудовании (возможно, с разным количеством оперативной памяти), это может быть связано с другим адресом, но обычно адрес также тот же, независимо от оборудования.

Но вы никогда не должны ожидать, что результат один и тот же! Короче говоря: не думайте о виртуальном или реальном адресе данных в вашей проге. Это находится под контролем компилятора, ОС и, возможно, некоторых библиотек. Так что просто игнорируйте это!

0

Короткий ответ: в программе пользовательского режима, работающей на компьютере с архитектурой x86-64: нет, вы не должны предполагать, что по какой-либо причине.


Длинный ответ: может случиться так, что адрес один и тот же, но это абсолютно не гарантировано (по крайней мере, для программы, работающей на ОС x86_64 и машине).

Я прочитал некоторую путаницу о виртуальной / физической памяти и как получается, что адрес «случайный«Итак, позвольте мне объяснить что-то на высоком уровне:

Ориентируясь на архитектуру x86_64 и ОС (скажем, Windows), вы даже не можете предположить, что сама операционная система загрузит все свои компоненты в память в тех же физических местах (некоторые исключения для старых соглашений о загрузчиках в 0000: 7C00H, Я понятия не имею, как это работает в среде UEFI).

После того, как сегментация (используется или не зависит от ОС, обычно Windows просто устанавливает несколько простых сегментов для режима пользователя и режима ядра), когда вы переключаетесь в защищенный режим (или длительный), вы снова не можете контролировать, как ОС управляет виртуальным механизм памяти, который скрывает уровни сложности и операции, связанные с MMU, чтобы дать вашему процессу собственное адресное пространство.

Кроме того, существуют меры безопасности: компоновщик может решить базовый адрес для вашего исполняемого файла, но в других случаях, когда ASLR активирована ОС может перемещать свои модули и ваш исполняемый файл, как это угодно в целях безопасности.

Вывод: если вы не имеете дело с вещами очень низкого уровня (например, физическими адресами или напрямую записывает области памяти на внешнем устройстве), вы абсолютно не должны полагаться на то, что адрес переменной является одинаковым при разных запусках. Там в без гарантии на что.

0
По вопросам рекламы [email protected]