最近在CCS 5.2上仿真C6678跑一个程序,来测试CPU 访问非对齐访问内存。
代码如下:
void main(void)
{
unsigned int *ptr;
//__packed unsigned int *ptr;
ptr = (unsigned int *)(0x800002);
*ptr = 0x12345678;
}
ptr无论指向的地址是0x800000,0x800001,0x800002,0x800003,通过查看内存,发现0x12345678都是写在0x800000,0x800001,0x800002,0x800003这几个地址上,这应该是CPU对齐访问造成的。
我有几个问题想问问:
1:查看编译生成的汇编代码,汇编代码并没有对地址进行处理,程序该访问什么地址,汇编就是写入的什么地址,那么对齐访问应该是CPU自己实现的?
2:CPU具体是怎么对齐访问的呢,能否简单的从硬件的角度说明一下
3:CPU默认是对齐访问,那么我想想之前写的代码就会有很大的隐患。比如代码中可能有很多char 类型的全局变量,那么,我在给一个全局变量赋值的时候,如果存在强制类型转换是非常危险的,因为会写入相邻几个地址?
Feng Gao7:
没人回答吗?
Shine:
回复 Feng Gao7:
可以看一下代码对应的汇编指令。
像STW指令要求Word addresses must be aligned on word (two LSBs are 0) boundaries.
Feng Gao7:
回复 Shine:
我查看了汇编指令,是这样的
这段是用unsigned int指针写0x0800001
30 ptr = (unsigned int *)(0x0800001);
0000d4c4: 020000AA MVK.S2 0x0001,B4
0000d4c8: 0200406A MVKH.S2 0x800000,B4
0000d4cc: 023C22F6 STW.D2T2 B4,*+B15[1]
32 *ptr = 0x12345678;
0000d4d0: 022B3C28 MVK.S1 0x5678,A4
0000d4d4: 02091A69 MVKH.S1 0x12340000,A4
0000d4d8: 01901FD8 || MV.L1X B4,A3
0000d4dc: 020C0274 STW.D1T1 A4,*+A3[0]
这段是用int指针写0x800002地址
30 ptr = (unsigned int *)(0x0800002);
0000d4c4: 0200012A MVK.S2 0x0002,B4
0000d4c8: 0200406A MVKH.S2 0x800000,B4
0000d4cc: 023C22F6 STW.D2T2 B4,*+B15[1]
32 *ptr = 0x12345678;
0000d4d0: 022B3C28 MVK.S1 0x5678,A4
0000d4d4: 02091A69 MVKH.S1 0x12340000,A4
0000d4d8: 01901FD8 || MV.L1X B4,A3
0000d4dc: 020C0274 STW.D1T1 A4,*+A3[0]
汇编似乎没有做什么特殊的处理,分别写的0x800001和0x800002地址。我还是不明白为什么都是写到0x800000,0x800001,0x800002,0x800003这4个地址。
另外,对于你说的 “像STW指令要求Word addresses must be aligned on word (two LSBs are 0) boundaries.”,如果我强制写的地址并不是4字节对齐,CPU或者汇编到底会怎么做?
Shine:
回复 Feng Gao7:
这是因为STW的指令要求。强制的不对齐的话,有STNW汇编指令和_mem4 内联函数。4.297 STNWhttp://www.ti.com/lit/ug/sprugh7/sprugh7.pdfTable 7-5. TMS320C6400, C6400+, C6740, and C6600 C/C++ Compiler Intrinsics (continued)http://www.ti.com/lit/ug/spru187u/spru187u.pdf