了解获取内存位置的两段代码
Understanding two pieces of code which fetch memory locations
我的任务是构建一个成功的引导加载程序,但会导致所有重要的问题,即它为何起作用。通过它,我被两行非常相似的代码难住了。
//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
转换为一个指针,returns 一个 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))
或者这是用括号矫枉过正,只是不需要吗?
你有一些正确的假设和一些错误的假设。
您似乎在记忆中的固定位置存储了 2 个值:
APPLICATION_ADDRESS + 0 +----------------------+
| Stack |
+ 4 +----------------------+
| pFunction |
+ 8 +----------------------+
现在让我们看看您的假设:
(__IO uint32_t*) APPLICATION_ADDRESS)
casts APPLICATION_ADDRESS
to be
a pointer which returns a 32-bit unsigned integer.
是的,正确。
This means if we go to address APPLICATION_ADDRESS
there will be another
address of a memory location holding a uint32_t.
接近但不正确。
在位置 APPLICATION_ADDRESS
你没有找到另一个整数地址,但在那里你找到了所述整数本身。
In *((__IO uint32_t *) APPLICATION_ADDRESS) we use the dereference
operator to gain the value the APPLICATION_ADDRESS
is pointing to.
是的。
好吧,有点迂腐,APPLICATION_ADDRESS
没有指向任何地方。它只是一个普通数字,而不是指针。这就是为什么您需要将所有类型转换为各种指针类型的原因。
The APPLICATION_ADDRESS
points to another address which holds a value
which will be returned. The (uint32_t)
then casts this value to be
uint32_t
.
不,APPLICATION_ADDRESS
是那个整数的地址。
Following my line of understanding renders the casting redundant as
you have already said the variable held is uint32_t within the
brackets.
正确。
This then contradicts my understanding of the next line. Why haven't
we defined APP_ADDRESS + 4
to be a pFunction within the brackets
initially?
从整数到指针的转换取决于实现。函数地址更多。如果内存内容定义为 32 位整数,则必须使用该类型读取它。然后,您可以根据需要进行任何转换。
这可能只会产生相同的值,也可能会有所不同。这取决于体系结构。
Finally I am confused with the difference in brackets arrangements.
Why does the dereference operator not surround the whole int_32
and
(APPLICATION_ADDRESS +4)
like so:
*((__IO uint32_t*) (APPLICATION_ADDRESS + 4))
or is this overkill with brackets and it is just not required?
不需要外括号。
内括号很重要。如果没有方括号,转换将比添加具有更高的优先级。那么你不会将 4 个字节添加到地址,而是 4 个内存对象的大小,这里将是 16 个字节。
我的任务是构建一个成功的引导加载程序,但会导致所有重要的问题,即它为何起作用。通过它,我被两行非常相似的代码难住了。
//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
转换为一个指针,returns 一个 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))
或者这是用括号矫枉过正,只是不需要吗?
你有一些正确的假设和一些错误的假设。
您似乎在记忆中的固定位置存储了 2 个值:
APPLICATION_ADDRESS + 0 +----------------------+
| Stack |
+ 4 +----------------------+
| pFunction |
+ 8 +----------------------+
现在让我们看看您的假设:
(__IO uint32_t*) APPLICATION_ADDRESS)
castsAPPLICATION_ADDRESS
to be a pointer which returns a 32-bit unsigned integer.
是的,正确。
This means if we go to address
APPLICATION_ADDRESS
there will be another address of a memory location holding a uint32_t.
接近但不正确。
在位置 APPLICATION_ADDRESS
你没有找到另一个整数地址,但在那里你找到了所述整数本身。
In *((__IO uint32_t *) APPLICATION_ADDRESS) we use the dereference operator to gain the value the
APPLICATION_ADDRESS
is pointing to.
是的。
好吧,有点迂腐,APPLICATION_ADDRESS
没有指向任何地方。它只是一个普通数字,而不是指针。这就是为什么您需要将所有类型转换为各种指针类型的原因。
The
APPLICATION_ADDRESS
points to another address which holds a value which will be returned. The(uint32_t)
then casts this value to beuint32_t
.
不,APPLICATION_ADDRESS
是那个整数的地址。
Following my line of understanding renders the casting redundant as you have already said the variable held is uint32_t within the brackets.
正确。
This then contradicts my understanding of the next line. Why haven't we defined
APP_ADDRESS + 4
to be a pFunction within the brackets initially?
从整数到指针的转换取决于实现。函数地址更多。如果内存内容定义为 32 位整数,则必须使用该类型读取它。然后,您可以根据需要进行任何转换。 这可能只会产生相同的值,也可能会有所不同。这取决于体系结构。
Finally I am confused with the difference in brackets arrangements. Why does the dereference operator not surround the whole
int_32
and(APPLICATION_ADDRESS +4)
like so:*((__IO uint32_t*) (APPLICATION_ADDRESS + 4))
or is this overkill with brackets and it is just not required?
不需要外括号。 内括号很重要。如果没有方括号,转换将比添加具有更高的优先级。那么你不会将 4 个字节添加到地址,而是 4 个内存对象的大小,这里将是 16 个字节。