ARM指令状态切换到Thumb指令状态
2018-10-21 来源:eefocus
AREA Arm_to_Thumb,CODE, READONLY
ENTRY
CODE32
start
ldr r0,=aaa+1
mov r3,#18
bx r0
CODE16
aaa
mov r1,#12
mov r2,#10
END
请看上面的代码,首先看到第一条指令,ldr r0,=aaa+1,aaa可以理解成一个函数的名字,那么函数aaa执行的时候是不是有第一条指令啊,这条指令是什么呢,那当然是mov r1,#12这条指令了,所以ldr那条指令的意思是:函数aaa的执行时的pc值+1,给r0寄存器,什么是pc值,就是程序计数器的意思,不懂的可以百度一下咯。至于这里为什么要加1,先不要急,看下面的语句,第二条语句是mov r3,#18,这个应该很好理解,我就不解释了,那么我把这么简单的指令放在这里干什么呢,为了说明这个程序计数器pc的变化过程,以便读者更好的理解随着程序的运行,pc值是怎么变化的。下面我贴一张调试到mov r3,#18那条指令是的图片,注意调试到mov r3,#18这条指令,并这条指令并没有运行,只不过是取址的状态,好了,话不多说,贴图:
注意上面的图片中的黄色箭头是我按单步执行后,按了一下后,箭头所在的位置,这时的R15的值是0x00000004,表示正在执行的指令的地址,当R15的值为0x00000000时,黄色箭头你说在哪里呢,当然是在ldr那条指令那里了,并且表示ldr指令并没有执行。请大家再看,R0的值为什么是0x0000000D呢,R0等于aaa+1,那么aaa是不是就等于十六进制的C啊,等于十进制的12啊,为什么会等于12呢,这就和R15寄存器有关了,待会运行到bx指令的时候再解释,我再单步进入,看截图:
大家只要看黄色的箭头即可。接下去是运行bx指令了,bx指令是什么东西呢,你们可以查阅相关资料,首先bx指令格式:BX{cond} Rm ,指令功能,BX指令跳转到Rm指定的地址去执行程序,若Rm的bit0为1,则跳转时自动将CPSR中的标志T置位,即把目标地址的代码解释为Thumb代码,如果为bit0位为0的话,则跳转时自动将CPSR中的标志T复位,即把目标地址的代码解释为ARM代码。
所以你先看看现在的R0的值是0x0000000D,bit0位为1,所以是把ARM指令状态跳转到Thumb指令状态,那么BX既然是一种跳转指令,则应该是偶数啊,D等于13不是偶数呀,这里我给你算算哈,当黄色的箭头指向mov r1,,#12,时,此时R15寄存器的值肯定是0x0000000C了,因为bx指令也是种ARM状态下的指令嘛,所以,当黄色光标指向mov r1,#12时,R15的值是0x0000000C了,这时你应该清楚为什么R0的值为0x0000000D了,就是C+1嘛,1只不过给个信号,我的程序要从ARM状态跳转到Thumb状态的程序中执行了。
T
所以请你猛看这里CPSR寄存器中的T位:从0(ARM状态)变成1(Thumb状态)
怎么验证已经到Thumb状态了呢,请看我再次运行哈:
这张图片中的R15是0x0000000E,上张图片的R15是0x0000000C,相差为2,所以说明已经转化成Thumb状态了,因为Thumb每条指令占用2个字节,16位。还有一点我想说明的是其实在你程序运行之前,每条指令的所对的PC值,是确定的,更为直观点的说法是,黄色箭头此时指向哪一条指令,这时的PC值你确定的,可以笔算的,注意全文所说的PC值就是R15寄存器的值。aaa只不过是一个函数的名字,取啥名儿都无所谓,zhangsan也行啊,哈哈。
啰嗦了半天,不知道有没有把这个转化过程讲清楚,如果还有不懂的,可以直接留言啊。
下面我想说说Thumb指令状态切换到ARM指令状态,原来和上述一样,这里我只贴个短小而精悍的代码了:
[plain] view plain copy
AREA Arm_to_Thumb,CODE, READONLY
ENTRY
CODE16
start
ldr r0,=zhangsan
mov r3,#18
bx r0
CODE32
zhangsan
mov r1,#12
mov r2,#10
END