本文主要是介绍TQ2440开发板学习纪实(9)--- 利用Undefined异常模拟BLX指令,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在博文 《紧急求助!ARM-GCC对于函数指针调用的编译有错误?》中,我提到了GCC在编译函数指针调用的时候,会生成绝对地址跳转指令BLX。而S3C2440A这款CPU不支持BLX指令,从而导致陷入Undefined异常。
本文就利用这个Undefined异常,来模拟BLX指令,从而让使用BLX指令的程序可以正常运行在S3C2440上。
1 Undefined异常的处理流程
ARM9在执行未定义指令时,会跳转到0x00000004处执行,进入Undefined模式,并把下一条指令的地址存入LR。
2 指令模拟的思路
利用Undefined异常处理的一个非常重要的作用就是用来扩展CPU指令集,模拟执行硬件不能直接支持的指令。原理非常简单,在Undefined异常处理中,通过(LR-#4)这个地址就可以获取未定义的指令,然而根据不同的指令写出不同的等价程序即可。
例如本节将要实现的BLX指令,下面是源码事例:
ldr r3, [pc, #32]
ldr r3, [r3]
mov r0, r2
blx r3
其中blx r3的等效源码为:
mov lr, pc
bx r3
需要注意的是:
- 进入Undefined异常处理时,CPU处于Undefined模式,此时的堆栈与异常前模式不同;
- 我们的模拟指令程序应该运行在原模式下,而不是Undefined模式下,否则无法获取原来的寄存器环境;
- 运行模拟指令程序前应保存所有用到的寄存器,运行返回前恢复。否则就会破坏原来的执行环境;
- 保存寄存器的通用方法就是入栈,而入栈保存需要一定的技巧来保证返回的同时恢复所有寄存器;
- 在Undefined模式下需要保存LR(此时存放的是原指令的下一条指令),此时不能通过入栈保存,因为Undfined的栈是独立的。变通方式,是存放LR的值到内存中。
3 BLX模拟实现
/* save the instruction's address after the undefined one. */.global AddrUnd
AddrUnd:.word
这篇关于TQ2440开发板学习纪实(9)--- 利用Undefined异常模拟BLX指令的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!