Может ли 32-битный процессор действительно адресовать 2 ^ 32 ячейки памяти? - PullRequest
8 голосов
/ 28 ноября 2011

Я чувствую, что это может быть странный / глупый вопрос, но здесь идет ...

В вопросе Требуется ли / определено ли значение NULL в C как ноль? , это былоустановлено, что указатель NULL указывает на неадресуемую область памяти, а также что NULL равен 0.

Теперь, предположительно, 32-разрядный процессор может адресовать 2^32 областей памяти.

2^32 - это только количество различных чисел, которые могут быть представлены с помощью 32 битов.Среди этих чисел 0.Но поскольку 0, то есть NULL, должно указывать на ничто, разве мы не должны говорить, что 32-разрядный процессор может адресовать только 2^32 - 1 области памяти (поскольку 0 не должен бытьдействительный адрес)?

Ответы [ 4 ]

9 голосов
/ 28 ноября 2011

Если 32-разрядный процессор может обращаться к 2 ^ 32 ячейкам памяти, это просто означает, что указатель C на этой архитектуре может ссылаться на 2 ^ 32 - 1 ячейку плюс NULL .

8 голосов
/ 28 ноября 2011

указатель NULL указывает на ячейку памяти без адреса

Это не правда. Из принятого ответа на поставленный вами вопрос:

Обратите внимание, что из-за того, как сформулированы правила для нулевых указателей, значение, которое вы используете для присвоения / сравнения нулевых указателей, гарантированно равно нулю, но битовая комбинация, фактически сохраненная внутри указателя, может быть любой другой вещью

Большинство платформ, о которых я знаю, на самом деле обрабатывают это, помечая первые несколько страниц адресного пространства как недействительные. Это не значит, что процессор не может решать такие задачи; это просто удобный способ сделать низкие значения недопустимым указателем. Например, несколько API-интерфейсов Windows используют это, чтобы различать идентификатор ресурса и указатель на фактические данные; все, что ниже определенного значения (65k, если я правильно помню), не является действительным указателем, но является допустимым идентификатором ресурса.

Наконец, то, что C что-то говорит, не означает, что CPU нужно ограничивать таким образом. Конечно, C говорит, что доступ к нулевому шаблону не определен, но нет никаких причин, по которым кто-то пишет в ассемблере, должен подвергаться таким ограничениям. Реальные машины, как правило, могут сделать гораздо больше, чем предписывает стандарт C. Виртуальная память, инструкции SIMD и аппаратный ввод-вывод - вот несколько простых примеров.

0 голосов
/ 28 ноября 2011

Во-первых, давайте отметим разницу между линейным адресом (AKA значение указателя) и физическим адресом.Хотя линейное адресное пространство действительно составляет 32 бита (AKA 2 ^ 32 различных байта), физический адрес, который идет к микросхеме памяти, не совпадает.Части («страницы») линейного адресного пространства могут быть отображены в физическую память, или в файл подкачки, или в произвольный файл, или помечены как недоступные и ничем не подкрепленные.Нулевая страница оказывается последней.Механизм отображения реализован на уровне ЦП и поддерживается ОС.

При этом нулевой адрес, являющийся не адресуемой памятью, - это всего лишь соглашение C, которое применяется каждой ОС защищенного режима начиная с первых Unices.В операционных системах реального времени эпохи MS-DOS нулевой дальний указатель (0000: 0000) был полностью адресуемым;однако, написание там разрушило бы структуры данных системы и не принесло бы ничего, кроме проблем.Нулевой ближний указатель (DS: 0000) также был идеально доступен, но библиотека времени выполнения обычно резервирует некоторое пространство вокруг нуля для защиты от случайного разыменования нулевого указателя.Кроме того, в реальном режиме (как в DOS) адресное пространство не было плоским 32-разрядным, оно было эффективно 20-разрядным.

0 голосов
/ 28 ноября 2011

Это зависит от операционной системы.Он связан с виртуальной памятью и адресными пространствами

На практике (по крайней мере, в 32-битном Linux x86) адреса являются байтовыми "числами", но большинстводля 4-байтовых слов они часто кратны 4.

И, что более важно, , как видно из приложения Linux , виден только максимум 3Гбайт из 4Гбайт,весь гигабайт адресного пространства (включая первую и последнюю страницы, рядом с нулевым указателем) не отображается.На практике процесс видят гораздо меньше этого.См. Его псевдофайл /proc/self/maps (например, запустите cat /proc/self/maps, чтобы увидеть карту адресов команды cat в Linux).

...