我知道取消引用空指针是未定义的 - 但我想知道在特定目标上发生了什么 - 一个MSP430。
我现在没有一块电路板可以在我面前加载它来测试它。
如果我这样做(或类似的话)会发生什么?
int * foo = NULL;
(*foo)++; //Crash?
位置0x0在SFR范围内并保留。
会产生PUC / POR吗?或者它会默默地“工作”?
生成的程序集是
;int * foo = NULL;
clr.w R15
;(*foo)++;
inc.w R15
因此,位置0x0实际上会增加1。
当我在模拟器中运行时,我看到地址0x0的值从0变为1.我在调试日志中没有警告,程序正常退出。
我使用的是IAR EW430编译器/汇编器/模拟器。
答案 0 :(得分:6)
不仅写入和读取地址0x0不会导致崩溃或重启,它实际上是MSP430应用程序经常使用的完全合法的操作。
初始部分或MSP430存储器映射保留用于I / O端口和控制寄存器:http://en.wikipedia.org/wiki/TI_MSP430#MSP430_address_space
特别是,0x0和后续地址的控制寄存器为:
#define IE1_ 0x0000 /* Interrupt Enable 1 */
#define IE2_ 0x0001 /* Interrupt Enable 2 */
#define IFG1_ 0x0002 /* Interrupt Flag 1 */
#define IFG2_ 0x0003 /* Interrupt Flag 2 */
因此,例如通过解除引用uint8_t *
或uint16_t *
指针将零写入该内存地址将禁用中断。通过解除引用uint32_t *
来写零也将清除标志。增加这些寄存器的值并没有多大意义,但应该是完全合法的。
至少在msp430系列1,系列2和系列4上就是这种情况。通过检查头文件,我无法在系列5上找到映射到0x0的任何内容(中断控制寄存器映射到从0x0100开始的区域) )。
因此,如果你想在代码中捕获NULL指针被取消引用的位置,那么你完全靠自己。