Понимание двух частей кода, которые выбирают области памяти - PullRequest
1 голос
/ 21 июня 2019

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

    //Get the application stack pointer (1st entry in the application vector table)
    appStack = (uint32_t) *((__IO uint32_t*) APPLICATION_ADDRESS);

    //Get the application entry address (2nd entry in the application entry table)
    appEntry = (pFunction) *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);

Я определил APPLICATION_ADDRESS.Я определил pFunction как указатель на функцию.Это моя попытка понимания:

(игнорирование __IO, поскольку это просто означает volatile)

(__IO uint32_t*) APPLICATION_ADDRESS) приводит APPLICATION_ADDRESS к указателю, который возвращает 32-битный неподписанныйцелое число.Это означает, что если мы перейдем к адресу APPLICATION_ADDRESS, будет другой адрес ячейки памяти, содержащей uint32_t.

В *((__IO uint32_t *) APPLICATION_ADDRESS) мы используем оператор разыменования для получения значения, на которое указывает APPLICATION_ADDRESSк.APPLICATION_ADDRESS указывает на другой адрес, который содержит значение, которое будет возвращено.(uint32_t) затем преобразует это значение в uint32_t.

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

Это противоречит моему пониманию следующей строки.Почему мы изначально не определили APP_ADDRESS + 4 как pFunction в скобках?

Наконец меня смущает разница в скобках.Почему оператор разыменования не окружает целые int_32 и (APPLICATION_ADDRESS +4), например, так:

*((__IO uint32_t*) (APPLICATION_ADDRESS + 4))

или это избыточное число в скобках, и оно просто не требуется?

1 Ответ

3 голосов
/ 21 июня 2019

У вас есть несколько правильных предположений и несколько неправильных предположений.

Кажется, у вас есть 2 значения, хранящиеся в фиксированном месте в вашей памяти:

APPLICATION_ADDRESS + 0  +----------------------+
                         |     Stack            |
                    + 4  +----------------------+
                         |     pFunction        |
                    + 8  +----------------------+

Теперь давайте посмотрим на вашипредположения:

(__IO uint32_t*) APPLICATION_ADDRESS) приводит APPLICATION_ADDRESS к указателю, который возвращает 32-разрядное целое число без знака.

Да, правильно.

Это означает, что если мы перейдем к адресу APPLICATION_ADDRESS, будет другой адрес ячейки памяти, содержащей uint32_t.

Закрыть, но не соответствует действительности.

В местоположении APPLICATION_ADDRESS вы не найдете другого адреса для целого числа, но там вы найдете само указанное целое число.

In *((__IO uint32_t *) APPLICATION_ADDRESS) мы используем оператор разыменования для получения значения, на которое указывает APPLICATION_ADDRESS.

Да.Ну, чтобы быть немного педантичным, APPLICATION_ADDRESS никуда не указывает.Это просто число, а не указатель.Вот почему вам нужно выполнить все приведения к различным типам указателей.

APPLICATION_ADDRESS указывает на другой адрес, который содержит значение, которое будет возвращено.(uint32_t) затем преобразует это значение в uint32_t.

Нет, APPLICATION_ADDRESS IS адрес этого целого числа.

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

Правильно.

Это противоречит моему пониманиюследующая строкаПочему мы изначально не определили APP_ADDRESS + 4 как pFunction в скобках?

Приведение от целого к указателю зависит от реализации.Еще больше для адресов функций.Если содержимое памяти определено как 32-разрядное целое число, вы должны прочитать его с этим типом.Затем вы можете сделать любое преобразование, если требуется.Это может привести только к одному значению или к другому.Это зависит от архитектуры.

Наконец меня смущает разница в скобках.Почему оператор разыменования не окружает целые int_32 и (APPLICATION_ADDRESS +4), например, так:

*((__IO uint32_t*) (APPLICATION_ADDRESS + 4))

или это избыточное число в скобках, и оно просто не требуется?

Внешние скобки не требуются.Внутренние скобки важны.Без скобок приведение будет иметь более высокий приоритет по сравнению с дополнением.Тогда вы не добавили бы 4 байта к адресу, но размер 4 объектов памяти, который был бы здесь 16 байтов.

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