ARM汇编中,关于arm/thrumb状态转换以及地址装载的问题:
问题描述:
从thumb指令跳转到arm指令区:
若要跳转的arm指令区的标号在本thumb指令区的前面,
也就是标号相对于当前pc的偏移量是负值,如果用adr
r1, expr来装载要跳转到地址,那么这时候会出错,说
是地址偏移超出范围,如果用ldr来装载地址则没有问
题;
若要跳转到arm指令区的标号在本thumb指令区的后面,
也就是标号相对于当前的pc的偏移量为正值,这时候无
论用adr还是ldr都没有问题。
相反,若从arm指令区跳转到thumb指令区,两种情况无
论是用ldr或者adr都没有问题。
造成这些区别的原因是什么呢?
下面的代码,预测一下结果:
area jump,code,readonly
entry
code32
start32
nop
nop
adr r0,thumb16+1
bx r0
nop
nop
nop
code16
thuumb16
nop
nop
nop
nop
ldr r0,=next32
bx r0
code32
next32
nop
nop
nop
adr r0,thu+1
bx r0
end
结果是从arm模式下用adr装载地址+1可以回跳到thumb
模式下(即使地址是负偏移),而在thumb模式下用adr
跳转则只能往后跳,不能往前跳,这个原因是因为在
thumb下,操作数的范围比arm模式的小,在这段代码里
,如果把thumb模式下的ldr r0,=next32修改成adr
r0,=start32,那么我们预计的结果应该是回跳,但是这
样做不行,在模拟器上运行,得到的相对地址是负数,
0xFFFFFFF6,越界了,所以不能这样做,而在arm模式
下操作数范围大些,所以可行。
在thumb状态下, ADR的表达式ADR register,expr,
其中,expr是地址表达式,偏移量必须是正数并小于
1kB。
问题描述:
从thumb指令跳转到arm指令区:
若要跳转的arm指令区的标号在本thumb指令区的前面,
也就是标号相对于当前pc的偏移量是负值,如果用adr
r1, expr来装载要跳转到地址,那么这时候会出错,说
是地址偏移超出范围,如果用ldr来装载地址则没有问
题;
若要跳转到arm指令区的标号在本thumb指令区的后面,
也就是标号相对于当前的pc的偏移量为正值,这时候无
论用adr还是ldr都没有问题。
相反,若从arm指令区跳转到thumb指令区,两种情况无
论是用ldr或者adr都没有问题。
造成这些区别的原因是什么呢?
下面的代码,预测一下结果:
area jump,code,readonly
entry
code32
start32
nop
nop
adr r0,thumb16+1
bx r0
nop
nop
nop
code16
thuumb16
nop
nop
nop
nop
ldr r0,=next32
bx r0
code32
next32
nop
nop
nop
adr r0,thu+1
bx r0
end
结果是从arm模式下用adr装载地址+1可以回跳到thumb
模式下(即使地址是负偏移),而在thumb模式下用adr
跳转则只能往后跳,不能往前跳,这个原因是因为在
thumb下,操作数的范围比arm模式的小,在这段代码里
,如果把thumb模式下的ldr r0,=next32修改成adr
r0,=start32,那么我们预计的结果应该是回跳,但是这
样做不行,在模拟器上运行,得到的相对地址是负数,
0xFFFFFFF6,越界了,所以不能这样做,而在arm模式
下操作数范围大些,所以可行。
在thumb状态下, ADR的表达式ADR register,expr,
其中,expr是地址表达式,偏移量必须是正数并小于
1kB。