|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
一、ARM处理器的特点
9 C8 O8 n/ N, n2 i
6 o! ?; u; [1 X$ y(1)支持的数据类型
, k. z+ C p# l. p9 c: Q0 y, F1 H/ E- f+ Z
A.字节 8bit; U! k/ G! a+ e# x
B.半字 16bit
, d; T F: s5 L3 u# _C.字 32bit Z4 ^* d. H+ M3 |# U
! W) Q" F4 p8 I
(2)采用32位精简指令集(RISC)处理器架构( ], c4 f2 `- f; n7 {/ T
7 t+ L/ F3 A4 W6 ]4 y$ CARM处理器可以工作在两种状态:
$ y. h j* h6 F9 `+ p3 J, W9 [& S* N- m! a5 A5 L. ]5 Y
A . ARM状态
2 r$ [# i$ _/ P# l& A* i% e- z/ O/ Y T
指令长度为32位,这种状态执行的是字对齐方式的ARM指令- u2 O; i* J; j
. c+ C/ q. s& Y* f. v0 n# N+ s* HB. Thumb状态0 F) P" N* L8 k
0 c& }8 R, n% q指令长度为16位,这种状态执行半字对齐方式的Thumb指令
# D. J9 k0 T( X/ B
3 S8 Y6 i& h, ^9 M主意:这两个状态间的切换并不影响处理器模式和寄存器内容
' j. a) E2 [. a; v3 t! }% Q
2 G' D" @+ i( _/ d小知识:RISC和CISC
5 i5 m0 g; ?, c- o- s
" N9 r0 b* _4 z9 c指令的强弱是CPU的重要指标,指令集是提高微处理器效率的最有效工具之一。从现阶段的主流体系结构讲,指令集可分为复杂指令集(CISC)和精简指令集(RISC)两部分。相应的,微处理随着微指令的复杂度也可分为CISC及RISC这两类。0 z* f+ y2 [4 Z% _1 R
, v' k) r4 m" I( ^9 K( nCISC是一种为了便于编程和提高记忆体访问效率的晶片设计体系。在20世纪90年代中期之前,大多数的微处理器都采用CISC体系——包括Intel的80x86和Motorola的68K系列等。即通常所说的X86架构就是属于CISC体系的。RISC是为了提高处理器运行的速度而设计的晶片体系。它的关键技术在于流水线操作(Pipelining):在一个时钟周期里完成多条指令。而超流水线以及超标量技术已普遍在晶片设计中使用。RISC体系多用于非x86阵营高性能微处理器CPU。像ARM(Advanced RISC Machines),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。而ARM体系结构目前被公认为是业界领先的32位嵌入式RISC 微处理器结构。所有ARM处理器共享这一体系结构。, @1 D: ~8 Q% t! F
/ c7 ?! ]3 C) ~* t, A(1)CISC
$ l. v4 G y% T# X, ]* R+ I# y6 g
CISC复杂指令系统计算机通过增强计算机指令系统功能,通过程序去执行大量功能各异的指令,从而优化计算机系统的性能。
% @0 {, ~& s' l: |' S" [- B0 e2 S; V7 R3 l9 j
由于具有大量的指令,因此CISC体系的优缺点也很明显。
" w' W: X! f6 a. b9 o
& a6 o* m3 ]" Y: h# M0 j优点:6 y" W, h4 H5 L+ Y9 b
( h4 T* v# O% e6 m& v! |
a)具有丰富的指令系统,很大程度上简化了程序设计的难度。# e0 u. S9 @5 N0 v
! r, J* ]" {) f) Pb)CISC中不要求指令长度统一,可以节省存储空间。
# f1 v9 S9 g8 K, R! y
' @$ t5 V; {( [c)CISC指令可以直接对存储器操作,使得通用寄存器数目较少。$ J6 K" r1 a7 g: U
* ]. U! ?0 p+ Q
同时CISC指令系统也带来很多问题:
J8 E5 G* @' W4 H
1 v+ M1 ^3 s3 x0 b m, ]a)由于指令系统庞大,寻址方式、指令格式较多,指令长度不一,增加了硬件复杂程序,设计成本较高。& ?. \& U7 ^' g, K
7 v9 Z$ N8 a6 ]4 B8 q1 G" {+ eb)指令操作复杂、执行周期长、速度低,难以优化编译生成高效的机器语言。& f1 ^ [3 I: ~% r. b7 z+ _% k
! }5 D) p, X* k6 m5 G4 ^& u1 X& |
c)许多指令使用频度低,增加了系统负担,降低了性价比。
! l# D, C4 |, n# D) A
9 }9 d* Q* J' q1 J7 q( K M(2)RISC
8 i$ G) d) c% X+ u$ k1 c
, l5 n" \' T* ?+ v) P; O6 s和CISC相比,RISC的指令就要少得多,通常在几十条左右,其基本设计思想是尽量简化计算机的指令功能,从而降低硬件执行指令的复杂度,因为软件比硬件容易提供更大的灵活性和更高的智能。因此CISC的主要特点如下:
! ]+ x+ M2 G* F/ I3 D$ v4 U0 m0 P* @: r2 F; S: E! }- K# k
a) 精简指令集:只保留了数量很少、功能简单、能在一个机器周期内完成的指令,如果要执行复杂的程序功能则通过子程序而不是使用复杂指令来实现。
9 t# o" N9 U! r* @8 C1 c4 q0 V5 l7 N% d/ s
b)指令长度相同:每条指令的长度都是相同的,可以在一个单独操作里完成。( P8 M& G% x" ?$ j" c- S
; c) [4 v1 [& ]( s
c) 单机器周期指令:大多数的指令都可以在一个机器周期里完成,并且允许处理器在同一时间内执行一系列的指令。" z; U. J) N2 ^. J; B
9 U" J0 G) {3 I7 b+ N0 M
使用RISC指令具有以下优势:5 R* t& |2 I% t: I) o$ F# x% a# t
+ P0 m. @. [5 o* H5 t/ j
a) 精简指令系统的设计适合超大规模集成电路的实现。由于指令条数相对较少,寻址方式简单,指令格式规整,与CISC结构相比,控制器的译码和执行硬件相对简单,因此芯片中用于实现控制器的晶体面积明显减小。
* P7 x- I3 `; u! Q- t" Q2 D
4 ~/ C/ v/ Z# s% db)在使用相同的晶片技术和相同运行时钟下,RISC系统具有更快的运行速度。精简的指令系统可以加快指令的译码,控制器的简化可以缩短指令的执行延时等,这些都可以提高程序的执行速度。
$ n% Q- d M2 Q6 F
) S; _5 p7 D4 I* w: lc)可以提供直接支持高级语言的能力,简化编译程序的设计。指令总数的减少,缩小了编译过程中对功能类似的机器指令的选择范围,减轻了对各种寻址方式进行选择、分析和变换的负担,易于更换或取消指令、调整指令顺序,提高程序运行速度。! }1 S% L- e$ m, C0 F8 b
$ D4 f+ L0 H" W! n: U
d)RISC处理器比相对应的CISC处理器设计更简单,所需要的时间将变得更短,并可以比CISC处理器应用更多先进的技术,开发更快的下一代处理器。
: g6 X" d* O% C4 E# J# C5 L& |! z/ X0 U: b' c) {
相应的,RISC也存在一些缺点,主要有:) |" u: ?/ {9 ?7 u
) k0 r7 r; Z, W( C
a) 由于指令少,因此加重了汇编程序员的负担,增加了机器语言程序的长度,从而占用了较大的存储空间。
6 w2 g8 I* g* Z+ k1 b# C% o! n
0 ]( {3 c9 y6 Ib) 相对来说,RISC对编译器的要求更高,因为指令简单,RISC结构的性能就依赖于编译器的效率。编译器的优劣直接影响处理器的性能发挥。 S+ o7 q/ A- s: H6 h
- a1 W1 X/ n# E9 d3 V) R7 a综合上面所述,若要再进一步比较CISC与RISC之差异,可以由以下几点来进行分析:
: n$ X* X9 k" u% j
" f! z4 H& H# a7 u2 L1、指令的形成:CISC因指令复杂,故采微指令码控制单元的设计,而RISC的指令90%是由硬体直接完成,只有10%的指令是由软体以组合的方式完成,因此指令执行时间上RISC较短,但RISC所须ROM空间相对的比较大,至于RAM使用大小应该与程序的应用比较有关系。7 |; E3 i0 a+ n* i0 G$ U% w5 H
6 k! |! D3 D2 k# |
2、定址模式:CISC的需要较多的定址模式,而RISC只有少数的定址模式,因此CPU在计算记忆体有效位址时,CISC占用的周期较多。1 b3 @. a$ l! E1 k7 g4 E k7 t, x
4 P) o. s5 b2 G& w& n/ t( k
3、指令周期:CISC指令的格式长短不一,执行时的周期次数也不统一,而RISC结构刚好相反,故适合采用管线处理架构的设计,进而可以达到平均一周期完成一指令的方向努力。显然的,在设计上RISC较CISC简单,同时因为CISC的执行步骤过多,闲置的单元电路等待时间增长,不利于平行处理的设计,所以就效能而言RISC较CISC还是站了上风,但RISC因指令精简化后造成应用程式码变大,需要较大的程式记忆体空间,且存在指令种类较多等等的缺点。
# F! u. e9 S4 }6 g$ ^# x! |- R' M) C0 k/ R# R8 W( K
4、大量使用寄存器
* n* w1 K% e5 y6 _ m' X0 n7 k/ B& ?' \+ G1 t
二、ARM处理器的模式与异常
, A4 a+ k" h% O# f+ l
* B8 O, \+ A/ J. WARM体系结构主要支持7种处理器模式,分别为 : 用户模式、快中断模式、中断模式、管理模式、中止模式,未定义模式和系统模式- B* N8 p- J+ K4 X& v: B' ^
' _9 T# N; F+ _
# j- r- e3 W# i" a. ?* C4 E' P(1)系统(sys),快中断(fiq)、中断(irq)、管理(svc)、中止(abt)、未定义(und)这六种模式成为特权模式
. G. h5 C! [1 [7 C3 ]
* O1 U2 s) \7 ]+ E+ }6 o2 Z6 T% v(2)快中断(fiq)、中断(irq)、管理(svc)、中止(abt)、未定义(und)
9 Q6 @8 `# `4 O7 t- @, ?% B2 Q. [
" c3 q+ j9 g+ y这五种成为异常模式* L! g: \$ G; [ L
T% z: _& \! t8 |# h' N# @. _& \% s9 Z! y# X5 q3 F
思考:为什么处理会被设计成这么多模式呢?
" X0 @0 C9 f9 c M/ U; |6 |! l% X ^( g' O
处理器之所以被设计出这么多模式的目的是为了能够更好地处理各种异常。& Z; S2 ~5 b( h6 n, L& A
! z9 Q, u+ T$ t5 U( z% @: }9 u
那什么是异常呢?所谓的异常,指的就是中止了程序正常执行的过程而不得不去完成的一些特殊工作,如芯片复位,取指失败,指令未定义,等等。& M. |6 K6 b& v+ |: c7 F) ]
7 [/ i& I- s% s
8 K$ Z6 m. v5 E9 z/ L$ c
有些同学在大学的时候,学过51单片机,知道中断的概念。在这里中断其实也是一种异常,这里的中断包括外部硬件产生的外部中断和由芯片内部硬件产生的内部中断。由中断产生的异常和其他异常,从处理方法的角度来看没有任何区别,所以我们可以把这些异常统一起来研究。
* v# J% g7 C$ B; Q; [& B! o4 i+ u! F
注意:在正常情况下,一个普通程序可能会运行在用户模式和系统模式下,当异常发生时,ARM就会自动切换到异常模式去处理异常,处理完后,又回到用户模式或系统模式下继续之前的工作。因为每一种模式都包含相应的私有资源,因此可以保证在处理异常的时候,原理的程序环境不会被新的环境破坏,从而保证了系统的正常工作。注意:在正常情况下,一个普通程序可能会运行在用户模式和系统模式下,当异常发生时,ARM就会自动切换到异常模式去处理异常,处理完后,又回到用户模式或系统模式下继续之前的工作。因为每一种模式都包含相应的私有资源,因此可以保证在处理异常的时候,原理的程序环境不会被新的环境破坏,从而保证了系统的正常工作。4 s$ C4 v; }& G; z7 \8 o1 q" d8 k& o
. z4 N# n' f* D. a" b3 i好了,关于ARM的异常和工作模式就介绍在这里,接下来我们来看看ARM每种模式下所拥有的寄存器。! f$ P& y! V; l& K: p% }' V4 G) o# i
% y( r- B0 O; p
三、ARM每种模式拥有的寄存器. C( I+ k, t4 [& o, r, ~
' ~7 F. V* b# }# W
前面我们讲到,ARM使用的是RSIC架构,而RSIC架构特点之一就是使用大量寄存器。ARM处理器支持多模式,每种模式都有一些寄存器是公用的,有一些是私有的。
3 Y# z' r' Q5 e9 E
5 \$ v( l! ^+ ]: M' L- w: o; |: _( H l" E, m- R9 b: P, T: [9 [
在这里可以简单总结一下:3 c. P8 w3 j c$ }# v9 I; |
3 `4 D* I7 @- f; Y8 t. f4 t
(1)ARM总共有37个寄存器,其中R0-R7,CPSR,R15(pc)是任何模式下都公用的的寄存器
2 ~, g" i+ ?+ I& L9 f8 v) |: H# X/ w& g, V" W$ f
(2)用户模式和系统模式使用相同的寄存器R0-R15,CPSR
- ^) L$ ]* @+ V0 \- `% y) x3 D t0 o; e7 {1 o. x1 p+ ]
(3)每种异常模式都有自己的 SPSR,R13,R14
7 g& V M) i4 L; J& i" a7 {( y& ^6 J2 i! Z
(4)FIQ模式除了公共R0-R7寄存器外,还有自己私有的R8-R12,其他模式没有自己私有的R8-R12寄存器& g* |' m& P) K" F( Q
# z! d, d# L* e u+ S注意:Cortex体系结构下有40个32-Bits长的寄存器Cortex-A多出3个寄存器,Monitor 模式 r13_mon , r14_mon, spsr_mon
- [( |$ C- k8 B- b- S. k* n3 q" q$ C( J, G g" g
接下来我们一起来看看这些寄存器都有什么作用吧。4 i0 N( Q4 I/ ?9 H
9 \; u2 T5 L6 n0 b1 Y四、ARM中每个寄存器的用途
! {2 J/ u* a" V" c/ ^/ L1 `$ j
0 w. W, e3 I$ C2 c; _2 @(1)R0-R12 这些寄存器我们可以随便使用,就像我们写C语言一样,都需要定义变量,在ARM的世界里,这些就是已经定义好的变量,可以直接拿来使用,每个都可以用来存放一个32bit的数哦。' H7 r. z: B: y% [0 q# v7 k3 [
- n; Y- J! n5 o7 @$ a& Q b(2)R13,R14这两个寄存器就要注意了,前面我们分析过,在所有的异常模式下都有自己的私有的R13,R14,即每种异常模式在操作R13和R14,不会对其他模式下R13和R14的值产生影响。
: ^8 _' S/ q2 E4 O
/ T; V* C# |8 m6 d" O7 vR13我们又叫做sp,也就是我们常说的栈指针。大家C语言的局部变量时需要入栈的,也就是说不管在那一种模式下,如果我们想调用C语言程序,那在之前先设置好对应模式的sp指针。7 t, U1 q) ^0 G. w& B2 K& j
1 F: b% g! \. u/ m
R14为链接寄存器(LR),在结构上有两个特殊功能:' Y8 n9 f6 y a: {+ \) Z
/ a* ~$ R2 A* {, w" }, T(1)在每种模式下,模式自身的R14用于保存子程序返回地址; i3 V3 a Q, w9 l0 H ~" i) v
1 X' ^: @7 M+ D+ S4 E {' i$ T b
(2)当发生异常时,将R14对应的异常模式设置为异常返回地址(有些异常有一个小的固定偏移量)。
! v# e: F' N! s+ f2 v1 e, Y
9 i5 s) z% I$ @8 p7 w(3)寄存器R15为程序计数器(PC),它指向正在取指的地址。也就说R15保存的是那一条指令的地址,CPU就会预取那一条指令。
7 L' w7 l: W$ y$ y
# I+ X( f1 v$ C(4)寄存器CPSR为程序状态寄存器,它时刻记录CPU的状态" s+ }9 [4 T5 E7 H
3 A; H! j5 I; i/ |6 ^
1 }$ L0 a0 v/ T4 S4 T3 ~/ H9 S通过上图我们可以知道,CPSR记录了处理器当前工作的模式,FIQ、IRQ中断是否使能,指令带条件执行结果等信息。7 k+ R9 b/ W2 k G j
7 z4 R$ a: G& i下面我们详细来看看每一位分别代表什么意思: m0 E! B# v$ h5 N9 @! n ^
: O: O7 j; D$ g8 f# u1 VA.条件代码标志: B) G6 S1 ~! T% \4 w$ Q
$ M' k# p( o9 s6 K: I(N ) 运算结果的最高位反映在该标志位。对于有符号二进制补码,结果为负数时N=1,结果为正数或零时N=0;/ k5 J5 U+ E% M% l8 ]' H6 ^
0 @; p A. B" ](Z ) 指令结果为0时Z=1(通常表示比较结果“相等”),否则Z=0;: O ~+ {5 X, E: D; r9 c* M3 m
5 j7 E2 w: Q# D( C2 G/ R+ t* X* [
(C ) 当进行加法运算(包括CMN指令),并且最高位产生进位时C=1,否则C=0。当进行减法运算(包括CMP 指令),并且最高位产生借位时 C=0,否则C=1。对于结合移位操作的非加法/减法指令,C为从最高位最后移出的值,其它指令C通常不变;+ A k# T' g1 o) k2 y
" C6 I: B. m. S2 J' p6 b: e) D
(V)进行加法/减法运算,并且发生有符号溢出时V=1,否则V=0,其它指令V通常不变。
1 G- u+ J2 Z4 l, d. u6 o4 b! Q& a6 b% j5 l6 n/ ]0 w+ a
B. 中断禁止位包括I和F位. p# i7 a* ?& s8 |4 u/ o R! a- J3 A
; ?% ^+ q- |; ]# l6 b当I位置位时,IRQ中断被禁止;- X. }. E: w1 ?
+ V9 _- W0 C+ d$ N' T" a( `当F位置位时,FIQ中断被禁止。7 |; C" `% H7 [
0 v, `% T& {& @3 t9 \ T/ Q( w8 p
C.T位反映了正在操作的状态# @+ [: t. O2 t* Y: `
Z/ [) t5 N$ b5 L& P4 I当T位置位时,处理器正在Thumb状态下运行;
" y, Y! k# o6 w8 p' p# M( i2 \9 k3 ?) I$ A; t) \
当T位清零时,处理器正在ARM状态下运行。
& ?$ A# F$ y# m% e o6 y
* k3 x+ j/ |# I- V: L* ^/ ^2 v6 LD.模式位" J/ l2 Y: _( W& F* u
' u$ ?/ [! q6 m" v+ Y7 C& v模式位包括M4、M3、M2、M1和M0,这些位决定处理器的操作模式。" x$ n( |& r+ K9 c! c$ X* w$ F1 }
5 Q2 j$ `+ B ~8 D
10000 User mode ; 10001 FIQ mode; 10011 SVC mode ; 10111 j- G0 A# w" O# _/ N6 f1 ?. V
8 N( i. M' J6 _& ~7 M- uAbort mode ; 11011 Undfined mode;
& Z) r l/ I v# W% Y% B: {+ m/ w. R* ^3 H
11111 System mode; 10110 Monitor mode; 10010 IRQ7 }. I5 U/ O3 I# l% K! t
2 Z$ @% {2 }4 C0 i0 {3 i注意:不是所有模式位的组合都定义了有效的处理器模式,如果使用了错误的设置,将引起一个无法恢复的错误
/ |5 X' O2 S( t9 p& r( K% m* q1 E5 S: w4 n3 Q
(5)SPSR 程序状态保存寄存器
; a$ v3 G" L7 z5 O1 J( Y0 ~9 ?! D. i1 D' u3 I% c+ ^, K5 c, x+ s# N
每种异常都有自己的SPSR,在因为异常事件而进入异常时它保存CPSR的当前值,异常退出时可通过它恢复CPSR。) \0 F( Q: X7 n v7 \4 n$ U5 t
, ?7 s3 a: q( |2 S2 C& g3 Q. r8 S0 p五、Thumb状态下的寄存器
1 h# p6 V" p- ?2 y$ Q1 h9 P
]5 V# Z6 k6 S& \" I0 _/ PARM状态和Thumb状态之间寄存器的关系" o2 y/ Y6 r. g
; a4 M8 @& c1 ^, V7 u% H$ e
Thumb状态寄存器与ARM状态寄存器有如下的关系:
1 t$ T& O; V& R+ y! a
9 j( ]: Y, D# m' k+ lThumb状态R0~R7与ARM状态R0~R7相同;9 [) g! D% g+ B* b/ F1 C7 g
" p2 G* e5 H. H( R8 F9 hThumb状态CPSR和SPSR与ARM状态CPSR和SPSR相同;
& g( D( `2 n( g- I
; [$ e U" a6 A7 qThumb状态SP映射到ARM状态R13;
! W1 w0 G- b3 A
6 r( r4 I6 j. @$ H2 x3 c. ?Thumb状态LR映射到ARM状态R14;
8 R/ M: [, l! K3 }3 n. \8 A5 C- U. V' F6 J: D* x
Thumb状态PC映射到ARM状态PC(R15)。, t4 G4 p; X" N+ z
' s8 d+ D& K$ M! p/ L
9 ], k; J. ^ w* z* K注意: 在Thumb状态中,高寄存器(R8~R15)不是标准寄存器集的一部分
# t, e0 H1 o3 P2 H" {8 @
; J) `+ q' o& @6 Z, t' D六、ARM异常处理3 r( E- W) p8 ]& [$ r
+ p& C8 `6 ?6 O f, h& R5 F前面我们已经说过异常了,所谓的异常可以理解为CPU的正常执行被打断,而不得不去完成一些特殊的工作。有些同学可能感觉还是有点抽象,举个例子说明一下吧:假如你正在努力的写代码,这个时候你肚子饿了,必须得解决呀,你就停止写代码,去吃饭了,吃完饭你又继续写代码了,过了一会,你的瞌睡虫来找你了,必须得睡觉呀,都三天三夜没睡了。睡完之后,你又开始写代码。这里的肚子饿,瞌睡虫就可以理解成异常情况,必须得处理,处理完后还得恢复以前的状态。
# |4 C9 a. X# K. B K; Z( g* v6 k" i7 F g0 k0 q
那异常产生的时候,硬件上会自动做那些事情呢?注意是硬件自动做的哦,不需要我们介入的。( m; M; q: U$ x" Z( {* @% f9 Q/ w
. o' v9 c1 ?: c) c) f" |. v: P6 p
当一种异常发生时,硬件就会自动执行如下动作:: c$ m+ p2 L- B( L
, H, v3 _ K% s% V. J/ O( O(1)将CPSR保存到相应异常模式下的SPSR中
% n1 D/ O) d2 K7 X6 k6 V$ u+ }4 R, H1 G. e, B! m' [5 I( y
(2)把PC寄存器保存到相应异常模式下的LR中9 r6 k2 E6 A& G9 Z# t$ E; B
5 _. m0 d% X: d8 o: |& N
(3)将CPSR设置成相应的异常模式
% T. o% h' \' g% [8 }/ ?% x$ Z# T6 r1 W5 x- t' k
(4)设置PC寄存器的值为相应处理程序的入口地址
. `& h, ]! C4 H/ { ?
" w3 v& ^% b+ ]5 R& a% T可以总结如下图:
1 A) m% {2 \1 S/ \$ q
* @. ^( {( w& Y4 ?, n/ |( e' }" o% g" q6 Y8 T! l& _. }, J
细心的同学就会发现,这里的PC寄存器的值不是应该指向正在执行的指令吗?为什么图中却指向了正在提起的指令,这里的"正在提取"又有什么含义呢?呵呵,这就涉及到流水线的问题了,关于流水线我们后面会介绍的。! Q8 K4 b1 U" S2 `9 A
l' [8 C# P4 W这里我们还是先搞明白,异常产生的时候,硬件应该将PC值设为多少呢?要想明白这个问题,还必须先知道一个概念"异常向量表"。
, F' y5 j+ w8 g: V' b9 @
/ g* J" e E& ~) g" W, yARM一共有5种异常模式,按道理,每一种异常模式都应该有一个唯一的入口地址。这些入口地址彼此相邻,我们一般称之为异常向量表。
/ G h8 ]: e: G5 }2 |- q4 B7 }- G+ f) v( R* y
; O5 N4 a$ O/ Z; @6 M当异常产生的时候,硬件会自动将PC的值设置为对应异常量的入口地址。具体异常向量表存放在什么位置,我们可以通过相关的协处理指令进行设置就可以了。这个我们在后期的课程中会讲到。$ Q" w& N" a+ N1 T$ l1 w7 Z2 S
: S& v6 x2 y/ h, s) }5 m0 J好了到这里,我们已经知道了,异常发生时,硬件都自动做了哪些事情。那异常返回的时候,硬件也会自动做一些事情吗?呵呵,答案是没有。异常返回的时候,程序员必须做如下事情:% {) e1 G3 E+ i
& @, u5 [+ \1 D! x1 K异常返回
5 H m! \: P/ S' l: k4 ?0 ?9 |4 P d1 t* R
(1)从 SPSR_<mode>恢复CPSR
. r0 n' I9 `! x: a M' c1 u- f
, P1 E% G# n E4 |6 A( G(2)从LR_<mode>恢复PC9 T* ?/ _) s/ o2 Z; m$ \, c
) P# L) ^5 \ s4 N, P' J, N这些事情产生的效果就是恢复现场哦。
0 E3 _5 I1 | j3 \0 j- R6 [8 D c+ H3 g( G2 M
$ s4 Y) K# r; @( C7 Z+ e
|
|