在ARM中,有两种形式的跳转方式:长跳转与短跳转。两种方式在本质上都是一样的:都是通过改变PC寄存器的值来实现指令的跳转。
长跳转
长跳转通过直接向PC寄存器中写入目标值来实现在4GB的地址空间中的任意跳转。这里解释下4GB是如何算出来的:我们知道汇编指令的寄存器是32位的,也就是说PC寄存器的最大值为232次方,说的更明白一点就是232=(210)*(210)*(210)*(22)=1024*1024*1024*4=1KB*1024*1024*4=1MB*1024*4=1GB*4=4GB。
短跳转
短跳转指令可以实现向前或向后32MB的地址空间跳转。目标地址的计算方法是将指令中的24位带符号的补码立即数扩充为32位(扩充其符号位),将此32位数左移2位后与PC寄存器值相加后写入PC寄存器中。跳转指令有如下四种形式:
- B:普通跳转指令
- BL:带返回的跳转指令,与变通跳转指令的区别是该指令在跳转前会将当前PC寄存器的值保存到LR寄存器中
- BX:带状态转换的跳转指令,它意味着指令跳转后,指令状态(ARM指令或Thumb指令)的切换。
- BLX:带返回和状态切换的跳转指令。
这里要说明下Thumb指令,该指令是将ARM指令集的一个子集重新编码而形成的一个指令集,指令的长度为16位。相比与ARM指令,Thumb指令集能够得到密度更高的代码。
应用
子程序调用
BL function
...
function
...
MOV PC, LR```
### 条件执行
下面的C语言判断语句用汇编实现:
if(a==0||b==1)
func1();
else
func2();
CMP R0, 0
CMPNE R1, 1
BEQ func1
BNE func2
...
func1
...
func2
...
### 循环
跳转到循环最先开始的地方,进而来达到循环的目的。
MOV R0,100
loop
...
SUBS R0, R0, #1
BNE loop
...