C 理解获取内存位置的两段代码
我的任务是构建一个引导加载程序,它已经成功了,但却引出了一个非常重要的问题,即它为什么工作。通过它的工作,我被两行非常相似的代码难住了C 理解获取内存位置的两段代码,c,memory-address,bootloader,C,Memory Address,Bootloader,我的任务是构建一个引导加载程序,它已经成功了,但却引出了一个非常重要的问题,即它为什么工作。通过它的工作,我被两行非常相似的代码难住了 //Get the application stack pointer (1st entry in the application vector table) appStack = (uint32_t) *((__IO uint32_t*) APPLICATION_ADDRESS); //Get the application entr
//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);
我已经定义了应用程序\u地址
。我将pFunction
定义为指向函数的指针。这是我的理解尝试:
(忽略\uuu IO
,因为这只是表示易失性
)
(\uu IO uint32\u t*)应用程序地址)
将应用程序地址
强制转换为返回32位无符号整数的指针。这意味着如果我们转到addressAPPLICATION\u address
,内存位置的另一个地址将保存一个uint32\u t
在*((\uu IO uint32\u t*)应用程序地址)
中,我们使用解引用运算符获取应用程序地址所指向的值。APPLICATION\u地址
指向另一个地址,该地址包含将返回的值。(uint32\u t)
然后将该值强制转换为uint32\u t
按照我的理解,将使强制转换变得多余,正如您已经说过的,保持在括号内的变量是uint32\t
这与我对下一行的理解相矛盾。为什么我们最初没有将APP_ADDRESS+4
定义为括号内的p功能
最后,我对括号中的不同安排感到困惑。为什么解引用运算符没有像这样包围整个int\u 32
和(应用程序地址+4)
:
*((__IO uint32_t*) (APPLICATION_ADDRESS + 4))
*((应用程序地址+4))
或者这是用括号括起来的过度使用,只是不需要?您有一些正确的假设和一些错误的假设
您似乎有两个值存储在内存中的固定位置:
APPLICATION_ADDRESS + 0 +----------------------+
| Stack |
+ 4 +----------------------+
| pFunction |
+ 8 +----------------------+
现在让我们看看你的假设:
(\uu IO uint32\u t*)应用程序地址)
将应用程序地址转换为
返回32位无符号整数的指针
是的,没错
这意味着如果我们转到addressAPPLICATION\u address
保存uint32\t的内存位置的地址
接近但不是真的
在位置APPLICATION\u ADDRESS
中,您找不到整数的另一个地址,但在那里可以找到所述整数本身
在*((\u IO uint32\u t*)应用程序地址中,我们使用解引用
运算符获取应用程序地址所指向的值
对。
嗯,说得有点迂腐,应用程序的地址不指向任何地方。它只是一个普通的数字,不是指针。这就是为什么需要对各种指针类型执行所有强制转换的原因
应用程序地址
指向另一个保存值的地址
这将被退回。(uint32\u t)
然后将该值强制转换为
uint32\u t
否,APPLICATION\u ADDRESS
是该整数的地址
按照我的理解,演员阵容是多余的
您已经说过,持有的变量在
括号
对
这与我对下一行的理解相矛盾。为什么没有
我们将APP_ADDRESS+4
定义为括号内的p函数
最初
从整数到指针的转换依赖于实现。函数地址更是如此。如果内存内容定义为32位整数,则必须使用该类型读取它。如果需要,您可以进行任何转换。
这可能只是产生相同的值,也可能不同。这取决于架构
最后,我对括号中的不同安排感到困惑。
为什么解引用运算符不包围整个int\u 32
和
(应用程序地址+4)
类似于:
*((__IO uint32_t*) (APPLICATION_ADDRESS + 4))
或者这是带有括号的过度杀戮,而这只是不需要的
不需要外部支架。
内括号很重要。如果没有括号,则强制转换将比添加具有更高的优先级。然后,您将不会向地址中添加4个字节,而是添加4个内存对象的大小,此处为16个字节。非常感谢您的帮助!非常感谢。