测试代码如程序清单 1.1所示:
程序清单 1.1
#include <stdio.h>
int main (int argc, char **argv)
{
sleep(2);
volatile int *a = (int *)0x40; //设置物理地址
printf("value = %x\n",*a); //读取物理地址中的值
*a = 0x12; //设置物理地址中的值
return (0);
}
2.模拟器运行结果在mini2440模拟器上的运行结果如图 2.1所示:
图 2.1模拟器运行结果
标号1处表示测试程序的加载地址,这里为0x60030000
标号2处表示引起错误的那条指令在内存中的地址,这里为0x600302ec
标号3处表示引起内存访问错误的地址,这里是0x40,意思是系统进行了一个访问0x40这个内存地址的操作,从而导致了内存错误
标号4处表示内存访问错误类型,这里是can not write,意思就是系统执行了一个写内存的操作,但是这个内存地址是不允许写的,从而引起内存错误
3.反汇编测试程序本测试程序是用debug模式编译所得,将测试程序和sylixos-objdump工具拷贝到同一个目录下,如图 3.1所示:
图 3.1拷贝测试程序和反汇编工具
在空白处按住shift并右击,选择"在此处打开命令窗口",如图 3.2所示:
图 3.2打开命令窗口
在打开的命令行中输入:arm-sylixos-eabi-objdump.exe -S -d 2440_test_app >app.dis,在同一目录下将生成一个app.dis反汇编文件,如图 3.3所示:
图 3.3生成反汇编文件
4.分析反汇编文件由之前分析得知,测试程序的加载地址=0x60030000,引起错误的那条指令在内存中的地址=0x600302ec。所以可以计算出引起错误的那条指令在内存中的偏移为0x600302ec-0x60030000=0x2ec。这个地址就是引起错误的那条指令在反汇编文件的汇编地址,如图 4.1所示:
图 4.1查看反汇编文件
可以看出0x2ec汇编地址处对应的是一条写内存指令,对应的c语句是"*a = 0x12",这就是源码中出错的地方。通过这个测试也发现了SylixOS下的一个有意思的地方,那就是非法地址可以读,但是不能写。