1.Arm中断响应过程(以IRQ中断为例):
If(处理器处于thumb状态下)
{
切换到arm状态;
}
将R0~R12放入irq中断模式下的堆栈中,堆栈指针由r13(irq)指明;
将当前状态寄存器cpsr的内容保存到spsr(irq)中;
设置当前状态寄存器cpsr中的相应位:位0~4控制位设为10010,位5即T位工作状态位设为0—arm工作状态,以及if位5、6中断禁止,禁止irq中断(当中断信号为reset 或者 fiq时,禁止新的fiq中断);
将引起异常指令的下一条指令的地址保存在r14中,—返回地址;
给程序计数器PC赋值,使其执行中断指令代码;
2.pc时刻指向正在取址的指令。
3.arm的三级流水线结构(中断调用原理):
Jmp Pc: Fetch decode execute L T
add Pc = pc + 4 Fetch decode execute
sub Pc = (pc + 4) + 4 Fetch decode execute
sub pc = ((pc + 4) + 4)+4 fetch decode
图示详解:
当jmp跳转指令执行完即execute之后,开始进入L周期,此时设置LR寄存器为当前pc值,在T周期硬件完成LR = LR – 4的工作,所以jmp指令返回时。LR中保存的返回地址为LR = PC+ 12 – 4即pc + 8,此时如果程序正确返回需要再执行-4操作,所以其返回指令为
Sub pc , LR, #4 硬件只完成一次-4操作,所以需要人工做一次sub操作。
疑问:arm子程序调用返回语句mov pc, LR 是什么原理
4.thumb指令集是无条件执行的,只有B指令是有条件执行的。
5.算数移位指令:右移最高位由符号位填充,左移由0补充。
6.指令mov r0,#0x0000f200(错误),因为指令格式里给立即数分配的空间只有12个字节,而这个立即数就是32位了,arm指令里立即数的存储必须用特殊格式,即立即数的12位包括八位常数和和四位的循环右移。其中循环右移的位数由一个四位的二进制的二倍表示(0000-1111)*2
比如:0x0000f200 首先提取出八位,要保证这八位能够通过逻辑右移得到原操作数,这里提取出f2,补充到32位,000000f2,逻辑右移24位得到原操作数,这是补充四个逻辑右移位,用逻辑右移24位的一半,即12,12:1100 ;f2:11110010 所以12位立即数位为110011110010
由此规则可知mov r0,#0xf3e是违反规则的,因为因为无法表示成4+8的形式。