Как я могу получить доступ к вектору прерываний, расположенному в местоположении машины 0? - PullRequest
2 голосов
/ 28 июля 2010

Как я могу получить доступ к вектору прерываний, расположенному в местоположении машины 0? Если я установлю указатель на 0, компилятор может преобразовать его в ненулевое значение внутреннего нулевого указателя.

Ответы [ 3 ]

2 голосов
/ 28 июля 2010

Вы правы, что в зависимости от вашей реализации C, внутренний нулевой указатель может не быть 0. Но обычно это так. Если вы хотите быть очень безопасным, вы можете ввести значение или использовать memset().

uintptr_t zerobits = 0;
void *pointer1 = (void *)zerobits;

или

void *pointer2;
memset(&pointer2, 0, sizeof pointer2);
2 голосов
/ 28 июля 2010

Если вы работаете в домене, где вам нужно читать / записывать векторы с нулевого адреса (я полагаю, вы находитесь на какой-то встроенной системе?), То вы найдете много того, что вы будете делать вне общей прямой интерпретации стандарта «С».

Можно с уверенностью предположить, что встроенные компиляторы будут генерировать доступ к адресам, которые вы указали в указателях, и не будут магически изменять их содержимое.

Однако вы не всегда можете предположить, что нулевой физический адрес в таблице данных - это то, к чему процессор обращается, когда вы читаете / записываете нулевой адрес. Если в процессоре есть MMU, то вам, возможно, потребуется пройти какой-то процесс логического -> физического отображения, и даже если нет MMU, многие современные небольшие встроенные процессоры играют в игры с адресным пространством вокруг прерывания векторы (например, загрузка из флэш-памяти, а затем, при необходимости, переназначение этой части адресного пространства в ОЗУ.)

1 голос
/ 28 июля 2010

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

Просто установите указатель на 0. (Это способ, который не должен работать, но если он имеет смысл, он, вероятно, будет.) Присвойте целое число 0 переменной int, ипреобразовать это int в указатель.(Это также не гарантированно работает, но, вероятно, будет.) Используйте объединение, чтобы установить биты переменной указателя на 0:

union {
    int u_p;
    int u_i;    / assumes sizeof(int) >= sizeof(int *) */
} p;

p.u_i = 0;

Используйте memset, чтобы установить биты переменной указателя на 0:

memset((void *)&p, 0, sizeof(p));

Объявите внешнюю переменную или массив

extern int location0;

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

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