作者:郭孝星
微博:郭孝星的新浪微博
博客:http://blog.csdn.net/allenwells
Github:https://github.com/AllenWells
一 寄存器
存储单元,32存储单元,4个字节的存储单元临时存放ALU运算结果的存储单元
Cortex-A R0到R15 为寄存器的编号
- R0~R7 1组 8
- R8~R12 2组 10
- R13 7组 7
- R14 7组 7
- R15(PC) 1组
- CPSR 1组
- SPSR 6组
ARM一共有40寄存器,这些寄存器有8种工作模式和4种状态,如下所示:
4种状态
- T=0;J = 1 处理器处于Jazelle状态
- T = 0;J=0; 处理器处于 ARM 状态
- T = 1;J=0 处理器处于 Thumb 状态
- T = 1;J=1 处理器处于 ThumbEE 状态
8种模式
- usr : 10000
- fiq : 高优先级的中断 (10001)
- irq : 低优先级的中断 (10010)
- svc : 软中断和复位 (10011)
- abort : 存和取 (10111)
- undef : cpu不识别的指令 (11011)
- system : (11111)
- mon : 安全模式 (10110)
同名寄存器访问的问题
当前模式处在irq
mov r13,#0 (irq的r13 )
切换模式到fiq
mov r13,#1 (fiq的r13)
切换模式到undef
mov r13,#2 (undef的r13)
切换模式到abort
mov r13,#3 (abort的r13)
二 异常处理
4大步与3小步,由cpu内核自动完成,不需要用户写程序。
- pc -> lr_mode
- cpsr -> spsr_mode
- cpsr <-
- T=0,J =0
- I,F 禁止
- cpsr[4:0] = mode
- pc = 异常向量
举例1
当前系统发生了irq中断10
- pc ->lr_irq
- cpsr-> spsr_irq
- cpsr <-
- T=0,J=0;
- I,F 禁止
- cpsr[4:0] = 10010(irq)
- pc = 0x18
举例2
发生了一个软件中断
- pc -> lr_svc
- cpsr -> spsr_svc
- cpsr <-
- T=0,J=0;
- I,F 禁止
- cpsr[4:0] = 10011(svc)
- pc = 0x08
异常返回
movs pc,lr
s: spsr-> cpsr
三 协处理器
每一个协处理器里面有16个寄存器C0 ~ C15 mcr p15,0,r0,c1,c0,0
- 4、ARM的后缀名:
- T : 支持THUMB指令
- D : 支持debug模式 ,支持片上调试
- M : 64位的长乘法指令
- I : 嵌入式ICE电路,用来获取cpu运算的状态
- S : TDMI的缩写
- E : 支持DSP指令
- J : 支持java字节码硬件加速的功能
- F : 浮点运算
四 流水线
4.1 三级流水线
第一周期
pc = 0x8000
pc与fetch之间的关系 Fetch = *pc
F : mov
D : x
E : x
第二周期
pc = 0x8004
F : add
D : mov
E : x
第三周期
pc = 0x8008
F : sub 0x8008
D : add
E : mov 0x8000
第四周期
pc = 0x800c
F : and 0x800c
D : sub
E : add 0x8004
4.2 分支流水线举例
第一周期
pc = 0x8008
F : orr
D : sub
E : bl 0x8fec
第二周期
L相当于E单元的子单元
E :L pc -> lr = 0x8008
pc = 0x8fec
F : and
D : x
第三周期
E : lr -4 -> lr = 0x8004
pc = 0x8ff0
F : orr
D : and
第四周期
pc = 0x8ff4
F : eor
D : orr
E : and
返回指令:
mov pc,lr (lr = 0x8004)
4.3 中断流水线
第一个周期(发生一个IRQ中断)
pc = 0x8008 -> 不变
F : mov -> 不变
D : sub -> 改变 DI(中断译码指令)
E : add -> 不变
第二周期
pc = 0x800c
F : x
D : mov
E : EI(中断指令)
第三周期
E : L (异常处理)
pc -> lr_irq = 0x800c
pc = 异常向量(0x18)
cpsr -> spsr_irq
cpsr <- TJ I F [4:0] = 10010
F : B 0xaf00
D : x
第四周期
E : A(lr -4 -> lr_irq = 0x8008)
pc = 0x1c
F : x
D : b 0xaf00
第五周期
pc = 0x20
F : x
D : x
E : b 0xaf00
第六周期
pc = 0xaf00
F :stmfd
D : x
E : x
第七周期
pc = 0xaf04
F : mov
D : stmfd
E : x
第八周期
pc = 0xaf08
F: ldr
D : mov
E : stmfd
stmfd是中断处理函数的第一条指令
中断返回: subs pc,lr,#4 (lr = 0x8008)
4.4 LDR流水线
M和W 是属于E单元的子单元,在M和W过程会占用E单元,占用E单元流水线阻隔
LDR互锁发生的条件
ldr指令中当前指令目的寄存器和下一条指令的源寄存器重名时会发生ldr互锁
LDM互锁:
LDMIA R13!, {R0-R3}
这条指令执行需要连续计算4次地址,所以需要占用E单元,占用4个周期
五 ARM汇编和C进行传参的标准
ATPCS:函数参数要求:
int func (int a,int b,int c ,int d ,int e)
- 第一个参数传给: R0
- 第二个参数传给: R1
- 第三个参数传给: R2
- 第四个参数传给: R3
- 第五个参数传给: 堆栈传递
参数的返回:
- 32位的返回值: R0
- 64位的返回值: 低32位R0 ,高32位R1
六 立即数的产生规则
一个字节的数,循环右移(ROR)0到30之间的偶数位得来的一个数就是立即数
判断规则:
0x1234,0x138,0x345,0xffffffff,0xf00012,0x12345678,0xf000000f,0x12,0x8
x y x x x x y y y
- 展开成二进制
- 从左端第一个非0数的左端偶数位开始断开 ,再从右端第一个非0数的左端偶数位断开
(保证断开的左端都为0 ,断开的右端都为0)
- 数断开之间的位数<= 8是立即数, > 8不是立即数
如下所示:
0x123
00 |01 0010 0011 |
0x348
00 | 11 0100 10 | 00
00 | 11 0100 0101 |
版权声明:当我们认真的去做一件事的时候,就能发现其中的无穷乐趣,丰富多彩的技术宛如路上的风景,边走边欣赏。