arm-linux-gcc 之 stmdb/stmfd/ldmia/ldmfd or push/pop ???

最近写中断嵌套汇编的时候发现这么一个问题:我的汇编语句被arm-linux-gcc更改了。熟悉编译器的人获悉给个“哦”!以为编译器不管是翻译一些C/C++,还是更底层的汇编语句,一定会对其有所更改。

在我看来,任何编译器只是按照自己的一套规则去翻译用户的语言。只是当编译通过的时候,大多数时候我们能运行自己的程序。如果不能呢?BUG!!!(它认为你的语言没有错别字,但是可能他不太会断句,是吧)。

话说回来,为实现操作系统的嵌套中断处理,我编写了如下语句:

Handleirq:
sub r14,r14,#4
str r14,[r13,#-0x4]
mrs r14,spsr
str r14,[r13,#-0x8]
str r0,[r13,#-0xc]
mov r0,r13
msr CPSR_c,#0xd3
ldr r14,[r0,#-0x4]
sub r13,r13,#4
str r14,[r13]
ldr r14,[r0,#-0x8]
sub r13,r13,#4
str r14,[r13]
ldr r0,[r0,#-0xc]
stmdb r13!,{r0-r12}
bl ext_irq_server
ldmia r13!,{r0-r12}
ldmia r13!,{r14}
msr spsr,r14
ldmia r13!,{pc}^   ;(这是最终正确版,欢迎使用)
在arm-linux-gcc-4.3.2上编译通过,但是程序只能执行中断处理程序,回不去中断之前的状态!毫无疑问在压栈出栈那块一定有问题。于是分析程序逻辑,压栈出栈、调整核心执行程序。最后在反汇编中找到了答案:
 
本来我使用的stmdb/ldmia等四字节压栈出栈指令被编译器转化为push/pop双字节压栈出栈。然后我修改Makefile 给arm-linux-gcc添加-O0选项,使其不优化我的语句,固执的编译器一如既往,于是它就被我无情换成了arm-linux-gcc-3.2.5版本。测试后在反汇编中就看到stmdb/ldmia等四字节压栈出栈指令!开心!
 
小结:编译有风险,多加小心。


2017/12/19
Carl
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值