|
在ARM中有2种方法可实现程序的转移:一种是用前面介绍过的传送指令直接向PC寄存器中写入转移的目标地址值,通过改变PC的值实现程序的跳转;另一种是下面要介绍的转移指令。
ARM的转移指令可从当前指令向前或向后的32位MB的地址空间跳转,根据完成的功能它可分为以下4种:
B——转移指令
BL——带链接的转移指令
BX——带状态切换的转移指令
BLX——带链接和状态切换的转移指令
1. 转移和转移链接指令
转移指令B在程序中完成简单的跳转指令,可跳转到指令中指定的目的地址。
在一个程序中通常需要转移到子程序,并且当子程序执行完毕时,能确保恢复到原来的代码位置。这就需要把执行转移前程序计数器PC的值保存下来。ARM使用转移链接指令BL来提供这一功能。BL指令完全像转移指令一样执行转移,同时把转移后面紧接的一条指令的地址保存到链接寄存器LR(R14)。
二进制编码
转移和转移链接指令的二进制编码如图
说明
转移和转移链接指令跳转的目标地址的计算方法是:先对指令中定义的有符号的24位偏移量用符号扩展为32位,并将该32位数左移2位形成字的偏移,然后将它加到程序计数器PC中(相加前程序计数器的内容为转移指令地址加8个字节),即得到跳转的目标地址。一般情况下汇编器将会计算正确的偏移。
转移指令的范围为±32MB。
转移指令的L位(第24位)置1时,表示是转移链接指令,它在执行跳转的同时,将转移指令的下一条指令的地址传送到当前处理器模式下的链接寄存器LR。这一般用于实现子程序调用,返回时只需要将链接寄存器LR的内容拷贝回PC。
2种形式指令都可条件执行或无条件执行
汇编格式
B{L}{<cond>} <target address>
L指定转移与链接属性;如果不包含L,便产生没有链接的转移。<cond>是条件执行的助记符扩展,缺省时为AL,即无条件转移。<target address>一般是汇编代码中的标号,是转移的目标地址。
举例
无条件跳转:
B TABLE ;无条件跳转…
…
LABLE… ;…到这里
执行10次循环:
MOV R0,#10 ;初始化循环计数器
LOOP …
SUBS R0,#1 ;计数器减1,设置条件码
BNE LOOP ;如果计数器R0不等于0,重复循环…
… ;…否则循环中止
调用子程序:
…
BL SUB ;转移链接到子程序SUB
… ;返回到这里
…
SUB … ;子程序入口
MOV PC,R14 ;返回
条件子程序调用:
…
CMP R0,#5 ;如果R0<5
BLLT SUB1 ;然后调用SUB1
BLGE SUB2 ;否则调用SUB2
…
注意:只有SUB1不改变条件码,本例才能正常工作;因为如果BLLT执行了转移,执行完子程序后,将返回到BLGE。如果条件码被SUB1改变,则SUB2可能又会被执行。
例如:
BL SUBR ;转移到SUBR
… ;返回到这里
…
SUB … ;子程序入口
MOV PC,R14 ;返回
注意:由于返回地址保存在寄存器里,在保存R14之前程序不应再调用下一级的嵌套子程序;否则,新的返回地址将覆盖原来的返回地址,就无法返回到原来的调用位置。这时一般是把R14压入存储器中的堆栈。由于子程序经常还需要一些工作寄存器,所以可使用多寄存器存储指令同时把这些寄存器中原有的数据一起存储。
BL SUB1
…
SUB1 STMFD R13!,{R0-R2,R14} ;保存工作和链接寄存器
BL SUB2
…
SUB2 …
不调用其他子程序的子程序不需要存储R14,因为它不会被覆盖。
注意事项
在上面第一个例子中,对于其他RISC处理器,可能将采用延迟转移模式,即在转移到标号LABEL之前会执行转移指令之后的指令。但是在ARMM中将不会出现这种情况,因为ARM不适用转移延迟的机制。
当转移指令转移到32MB地址空间的范围之外时,将产生不可预测的结果。
凌阳教育,专注嵌入式人才培养多年,完善的培养方案,强大的师资,合理的课程安排,成功从小白蜕变为嵌入式工程师。想了解凌阳教育,或者获得更多嵌入式学习资料的免费下载,请点击www.sunplusedu.com访问凌阳教育官网