我试图访问内存地址0,它被定义为ROM的起始地址,以检查我的配置是否正确以及该区域是否可访问。但当我编译代码时,产生的反汇编显示该操作未定义。
0确实是NULL并且可能被视为未定义,但是对于访问内存地址0处的内容,是否有任何解决方法?
下面是测试代码:
#include <stdio.h>
int main ()
{
printf("%08X", *(unsigned int*)(0));
}
当用arm gcc和选项-Os
编译时,得到反汇编结果。
main:
mov r3, #0
ldr r3, [r3]
.inst 0xe7f000f0
可以看出,代码在.inst 0xe7f000f0
处结束,并且printf
未被调用。
该代码也可以在Compiler Explorer中找到。
1条答案
按热度按时间x759pob21#
最简单的方法是通过链接器脚本Map绝对地址为零的对象,然后访问该对象,而不是尝试创建一个指向地址零的指针。
对于ARM Cortex M,工具链很可能已经为您完成了这一工作,其形式为向量表+地址0及以上的特殊寄存器。只需使用工具链提供的标识符,或者在不太可能出现的情况下,创建您自己的自定义链接器脚本,并在物理地址0分配变量。
至于问题中的“语言律师”部分:
0确实是NULL并且可能被视为未定义,但是对于访问内存地址0处的内容,是否有任何解决方法?
不完全是。
NULL
是一个空指针常量,0
是一个空指针常量,这两个常量中的任何一个都可以用来创建空指针,就像在代码中将0
转换为对象指针类型一样。请参阅What's the difference between null pointers and NULL?,我试图澄清空指针、空指针常量和
NULL
宏之间的区别。至于取消引用空指针,根据一元
*
运算符规范6.5.3/4,它 * 是 * 未定义的行为:如果为指针分配了无效值,则一元
*
运算符的行为未定义