Почему ячейка 0x00000000 доступна, если это флеш-память

Насколько я знаю, ячейка памяти 0x00000000 недоступна через указатель в C, но недавно в моем проекте я смог получить доступ к нулевой ячейке с помощью указателя. Нулевая позиция - это флэш-память. Но согласно сообщению Почему нулевой адрес используется для нулевого указателя ? ссылка на ноль через указатель является зарезервированным значением. Итак, мой вопрос: поскольку это зарезервированное значение, почему это не верно для памяти, отображаемой для флэш-памяти в нулевом местоположении?

Процессор: TMS470Rxx

ОС: Micro C OS-II

Спасибо


person geek    schedule 20.11.2015    source источник
comment
Вы спрашиваете нас, почему вы столкнулись с определенным поведением, зависящим от конкретной платформы, на какой-либо платформе, но вы не сказали нам ничего об этой платформе. Какой процессор? Какая ОС? Кроме того, как узнать, что причина в том, что нулевая точка - это вспышка? Если вы знаете что-то, чего не знаем мы, поделитесь этим, потому что в противном случае у нас не будет никакой надежды разгадать эту загадку с еще меньшим количеством ключей, чем у вас.   -  person David Schwartz    schedule 20.11.2015
comment
0x0 - зарезервированное значение с точки зрения C, но если ваша платформа может получить к нему доступ, вы могли бы увидеть этот адрес. Например. Микроконтроллеры, такие как PIC16 или Cortex M, по адресу 0 хранят iPC, по адресу 0x4 хранят ISP, и вы можете указать и прочитать его.   -  person LPs    schedule 20.11.2015
comment
Вы также можете проверить Могу ли я когда-нибудь захотеть получить доступ к нулевому адресу?   -  person Bo Persson    schedule 20.11.2015
comment
Вам действительно следует уточнить, относится ли это к вопросу C, вопросу C ++ или каким-то образом связан с обоими языками. Потому что правила для NULL очень разные, и ваш вопрос, кажется, конкретно основан на том, что вы знаете об указателях C. (Что, кстати, неверно. Хотя почти правильно для C ++.)   -  person David Schwartz    schedule 20.11.2015
comment
Есть огромная разница между тем, можно ли что-то делать и возможно ли это. Вы также должны прочитать вопрос, на который вы ссылаетесь, и ответы на него, пока не поймете разницу между нулевым адресом и нулевым указателем.   -  person molbdnilo    schedule 20.11.2015


Ответы (2)


Решение о том, что происходит при использовании того или иного адреса, довольно сложно. Это зависит от архитектуры процессора, ОС и иногда «того, что делает какое-то программное обеспечение».

У процессора может не быть защиты памяти, или нулевой адрес действительно может быть «использован для чего-то» (в реальном режиме x86, в котором работает DOS, нулевой адрес содержит таблицу векторов, где прерывания и другие переходы, поэтому он невероятно чувствителен к перезаписываются - следовательно, плохо написанные программы могут и могут привести к сбою не только себя, но и всей машины в DOS).

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

ОС может иногда разрешать доступ к нулевому адресу: много лет назад у меня была ошибка в драйвере Windows, который использовал NULL-указатель, и что в этой конкретной ситуации адрес 0 не вызывал сбоя. Авария произошла намного позже, когда содержимое нулевого адреса использовалось для чего-то - в этот момент система отображала синий экран (по крайней мере, пока я не подключил отладчик и не отладил проблему, а затем исправил ее, чтобы она не пыталась использовать указатель NULL - я не помню, нужно ли было выделить какую-то память или просто пропустил этот бит, если указатель был NULL).

Выбор 0 для NULL основан на комбинации «мы должны выбрать какое-то значение (и нет ни одного значения, которое можно было бы на 100% быть уверенным в том, что никому никогда не понадобится)» - особенно на машинах с 16 или 32 -битовый диапазон адресов. Однако обычно нулевой адрес, если он используется, содержит что-то «особенное» (векторную таблицу для прерываний, код начальной загрузки для процессора и т.п.), так что вы вряд ли будете в нем значимо хранить данные. C и C ++ как языки не требуют, чтобы NULL-указатели были недоступны [но также не «позволяют» вам свободно обращаться к этому местоположению], просто это значение может использоваться как «указатель, который ни на что не указывает. "- и спецификация также предусматривает случай, когда ваше значение NULL НЕ ДЕЙСТВИТЕЛЬНО равно нулю. Но компилятор должен иметь дело с «ZERO означает NULL для указателей, поэтому замените его на X».

Нулевое значение, по крайней мере, иногда, имеет преимущество перед другими значениями - в основном, у многих процессоров есть специальные инструкции для сравнения или определения нуля.

person Mats Petersson    schedule 20.11.2015
comment
Многие системные функции POSIX, такие как mmap() и shmat(), также возвращают -1 для недопустимого указателя вместо NULL, потому что иногда 0 является допустимым адресом памяти для них < / а> - person phuclv; 09.10.2020

Есть много платформ, на которых нулевой адрес ведет себя иначе, чем на типичном настольном ПК.

Существуют микроконтроллеры, в которых аппаратные устройства отображают память в нуле устройства.

Существуют операционные системы, которые с радостью позволят вам специально сопоставить что-то с нулевым адресом, если вы захотите. Если у вас есть записываемая флеш-карта, вы можете писать туда.

Разные платформы работают по-разному.

person David Schwartz    schedule 20.11.2015
comment
Процессор: TMS470Rxx, ОС: Micro C OS-II. Есть комментарии по этой платформе? - person geek; 20.11.2015