内存不对齐访问(unaligned access)及汇编下宕机—ARM架构从入门到砸板跑路

         lucifer做arm汇编开发,在访问一个.data段的空间(全局变量)时,发生了宕机;未见进入数据中止异常,和未定义指令异常的处理函数中,让我一脸懵逼。

         接着查资料发现,发现对内存进行加载和存储的指令具有如下限制:
LDRB/STRB          - address must be byte aligned
LDRH/STRH          - address must be 2-byte aligned 
LDR/STR            - address must be 4-byte aligned

即用内存访问指令间接寻址时,所访问的地址应是所要求对齐字节数的整数倍

        否则,即进行了不对齐访问(unaligned  access),这时会发生“宕机”或者“一切安好”。


        如下详细介绍发生不对齐访问的情况,和提供数种解决宕机方案

(1)发生不对齐访问的代码例子:


          如图中line113和line123,使用ldr指令通过标签isr_countisr_tmp访问了.data段里两个4Byte的空间;而isr_countisr_tmp在汇编器处理后得到如右图所示的地址,由于用来存储字符串的fmt_timer_init中的Line3240对应的机器码只占3Byte的空间,导致后续存储机器码的内存地址,丧失了4Byte对齐。

          uboot启动后,运行上述裸机代码,将会发生宕机,原因分析如下:

 

          uboot的cpu内核初始化阶段,启动了内存地址对齐错误的检查功能;然后用ldr加载和str存储内存地址不对齐的空间会发生什么事情?

          参考ARM架构手册中如下表,可知将因指令的地址对齐错误导致数据中止异常如果你用如下指令将SCTLR.A置0,将不会产生异常,实现了不对齐访问,较早的ARM架构不支持这种功能,ARMv7上可以支持。

mrc p15, 0, r0, c1, c0, 0;  Read SCTLR
bic r0, r0, #0x2;           clear SCTLR.A
mcr p15, 0, r0, c1, c0, 0;  Write SCTLR


          另外如果你在linux kernel运行过程中出现了alignment fault,可以考虑检查汇编部分的操作。


(2)各种解决alignment fault方法:

       ①使用汇编伪操作.align {alignment} {,fill}

.data
fmt_timer_init: 
	     .string "timer_0_4_init()\r\n"
fmt_t0:
	     .string "timer0_isr()\r\n"
.align   	                        @avoid string breached address 4 byte align
isr_count:
	     .int 0
isr_tmp:
	     .int 0
.end

        对齐方式设置伪操作.align通过用零或指定的数据进行填充,来使得当前位置与指定的边界对齐;上述代码中.align没有指定对齐方式和所要填充的数据,则默认情况下是字对齐(4Bytes)并用零填充,即指定了isr_count的地址为4Byte对齐。汇编后再反汇编得到的结果如下图所示:


       ②先定义int数据,再定义string数据

          从上面中可知道由于string定义的字符串空间破坏了data段地址的字对齐,那我们就通过规避string来达到int数据空间字对齐的目的;

    

         ③在C语言环境用C来代替发生misalign的代码

         在uboot上,尽最大可能让代码在C语言下执行,及早进入C语言环境,让交叉编译器去帮我们执行这些对齐的操作。另外裸机代码为了保证各个section起始地址为4字节对齐,通过在链接文件中添加:

. = ALIGN(4);
         如uboot的链接文件:
 


 嵌入式系统发展非常迅速,新的技术成果不断更新。上述博文难免存在错误和不妥之处,恳请各位看客批评指正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值