EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 piday123 于 2020-10-12 16:08 编辑 % ~2 z7 u. W9 Z2 o$ t" n" I M
- |" r1 }$ [/ B- P8 K% W P* C第一章:ARM概述及其基本编程模型 1.4 arm处理器模式 arm体系结构支持7中处理模式。 用户模式 (usr) 正常程序执行的模式 快速中断模式(fiq) 用于高速数据传输和通道处理 外部中断模式(irq) 用于通常的中断处理 特权模式(svc) 供操作系统使用的一种保护模式 数据访问中止模式(abt) 用于虚拟存储及存储保护 未定义指令中止模式(und) 用于支持通过软件仿真硬件的协处理器 系统模式(sys) 用于运行特权级的操作系统任务 备注:除用户模式为,其他的六种模式成为特权模式,而除系统模式外,剩下的五种模式又成为异常模式。每种异常模式都有特定的2个寄存器,用来保存特定异常模式的状态信息。
, Z. i# {, U" p8 x* |$ ?1.5 arm共有37个寄存器,可以分为两类: 1、通用寄存器31个 R0~R7共8个未分组寄存器,所有处理模式下都是同一个物理寄存器。 R8~R14有两个分组,一个分组为R8~R12,为fiq模式单独用了5个寄存器,故有10个寄存器。 另一个分组为R13~R14分组寄存器,5(异常模式)x2+2(用户模式和系统模式共用)共12个寄存器。 R13和R14都有特定的用途。一般R13用作堆栈指针。R14用作连接寄存器,保存子程序或者异常返回地 址,当然也可以当做通用寄存器。 R15为程序计数器,即PC。当向R15写入正常的地址时,程序将转向该地址并执行。注:由于arm指令是字对齐的,而存储结构中是按照字节存储的,也就是存储中的每一位代表一个字节,故要求写入R15的地址应该为4的倍数,也就是要求bits[1:0]=0b00。 2、状态寄存器6个 CPSR,7种模式共用,保存当前程序的状态信息。包括条件标志位、中断禁止位、当前处理器模式标志以及其他一些控制和状态位。 SPSR,5种异常模式各有一个专用的备份程序状态寄存器。当特定的异常中断发生时,用来保存CPSR中的内容,直到退出异常程序,再将保存的内容恢复到CPSR中。 关于状态寄存器的状态信息: 1、bits[31:28],条件标志位,分别保存N(表示结果正负)、Z(表示结果是否为零,CMP指令,=1表示相等)、C(进/借位标志,受加/减运算影响)、V(表示符号溢出,受加/减运算影响) 2、bit[27],Q标志位,在E系列处理器中表示增强的DSP指令是否发生溢出。 3、bits[7:0],控制位,分别为I(IRQ中断控制)、F(FIQ中断控制)、T(Thumb指令控制)、M[4:0](处理器模式控制)
! w) ?) [9 W( X# ~% i$ x1.6 arm异常中断 arm共有7种异常中断,包括复位、未定义指令、软件中断、预取指令中断、数据访问中止、外部中断、快速中断。 异常中断响应过程: 1、保存CPSR到将要执行的相对应SPSR中。 2、重新设置CPSR相应位,使处理器进入相应的中断模式。 3、将相应的链接寄存器LR_mode设置为返回地址。 4、将PC设置为异常中断的中断向量地址,及跳转到异常中断程序中去执行。 5、将SPSR内容送CPSR,将LR_mode送PC。
4 a9 a. Y4 |& \9 u1.7 arm体系中存储系统 arm存储以字节为单位,地址空间为2^32个字节共4G空间。 arm存储格式有小端结尾(低字节存储在低位,即由小到大)、大端结尾(最高字节存储在低位,即由大到小)。 arm存储访问由对齐访问和非对齐访问。 / r8 U, r; |0 c" T- E* H: W% `, ^
第二章 ARM指令分类及寻址方式 2.1arm指令概述 arm指令共6种,分为:跳转指令、数据处理指令、程序状态传输指令、Load/Store指令、协处理器指令、异常中断指令 arm指令长度固定为一个字长,即32位。 典型的arm指令编码格式为 ; e* N6 s0 w1 ?% }0 x. p: ?
& t0 `' w% R' L' q6 \4 c( ~
典型的arm指令语法格式为: <opcode> {<cond>} {s} <Rd>, <Rn>, <shifter_operand> 其中:<opcode> 指令助记符,如ADD表示算术加操作指令 {<cond>} 表示指令执行条件,大括号表示可选 {S} 指令操作是否影响标志位 <Rd> 表示目标寄存器 <Rn> 表示第1个操作数的寄存器 <shifter_operand> 表示第2个操作数 arm指令条件码域
2 [6 V5 }9 w$ V% {, T$ A
3 a- \% I& }2 M$ ^: ^& s- k
2 ^; b8 T- g* Q5 s. J2.2 arm指令寻址方式 1. 寄存器寻址: MOV R1,R2 ;读取R2的值到R1中 SUB R0,R1,R2 ;将R1的值减去R2的值,结果保存到R0中 : T7 J ~2 y. b1 |
2.立即寻址: SUBS R0,R0,#1 ;R0减1,结果保存到R0中,并影响标志位 MOV R0,#0xFF000 ;将0xFF000存储到R0中
b5 M- Q- G9 n S3 E0 w) o 3. 寄存器移位寻址: MOV R0,R2,LSL #3 ;R2的值左移3位,结果存入R0 ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,然后与R1相与,结果存入R1. 移位操作有这样几种: LSL,LSR,ASR,ROR,RRX,具体含义可以查相关手册 , n: g; V; D* r2 q: F+ A
4.寄存器间接寻址: LDR R1,[R2] ;将R2指向的存储单元的数据读出,保存到R1中 SWP R1,R1,R[2] ;将R1的值与R2指定的存储单元的值进行交换.
. s9 _7 ?: J! s4 ?, ~ 5.基址寻址: LDR R2,[R3,,0x0C] ;读取R3+0x0C地址上的存储单元的内容,存入R2中 STR R1,[R0,#-4]! ;先R0=R0-4,然后把R1的值保存到R0指定的存储单元 LDR R1,[R0,R3,LSL #1] ;将R0+R3*2地址上的存储单元中的内容读出,保存到R1中. ) U* c* ~1 F( e7 b
6.多寄存器寻址: LDMA R1! {R1-R7,R12} ;将R1指向单元的数据读出,放到R1~R7,R12中,R1自动加1 STMIA R0!,{R2-R7,R12} ;与上面方向相反,R0自动加1 我总感觉书中写的方向不对
% ~: Q# y4 f/ p 7.堆栈寻址: STMFD SP!,{R1-R7,LR} LDMFD SP!,{R1-R7,LR} 可以参考前面的例子,只不过是堆栈SP寄存器而已 ) c& L' @2 H) S9 R5 F6 o! [6 k' ]( X
8.块拷贝寻址: STMIA R0,{R1-R7} STMIB R0,{R1-R7} STMDA R0! {R1-R7} STMDB R0! {R1-R7}
2 s$ `' s6 Z8 ~ 9.相对寻址: BL SUBR1 ;调用到SUBR1子程序 BEQ LOOP ;条件跳转到LOOP标号处 1 _( D. D+ y+ @. U! N, A
第三章 ARM指令集 1、跳转指令 — 使用专门的跳转指令。 32MB 地址空间 ?0 o; P& G+ {' B5 j2 x0 L0 ]
— 直接向程序计数器PC 写入跳转地址值。 4GB 地址空间 — B 跳转指令
. M% p/ E. \9 ~— BL 带返回的跳转指令& T9 v: }% Z" g+ y j$ x, i4 _" p
— BLX 带返回和状态切换的跳转指令
/ ?* E% c$ g6 `% x— BX 带状态切换的跳转指令 B{条件} 目标地址 其他的类似 2、数据处理指令
% r ^' c' V# _- D z数据处理指令可分为数据传送指令、算术逻辑运算指令和比较指令等。 数据传送指令用于在寄存器和存储器之间进行数据的双向传输。 算术逻辑运算指令完成常用的算术与逻辑的运算,该类指令不但将运算结果保存在目的寄存器+ C+ [+ F6 [- Z# f; E! R
中,同时更新CPSR 中的相应条件标志位。
5 t! t- E; ?* p; _$ q+ R比较指令不保存运算结果,只更新CPSR 中相应的条件标志位。 数据处理指令包括: — MOV 数据传送指令 MOV{条件}{S} 目的寄存器,源操作数 MOV R1,R0 ;将寄存器R0 的值传送到寄存器R1; {! m$ l5 d! V) t: P
MOV PC,R14 ;将寄存器R14 的值传送到PC,常用于子程序返回
' `# E) U& q: l; QMOV R1,R0,LSL#3 ;将寄存器R0 的值左移3 位后传送到R1 — MVN 数据取反传送指令 MVN{条件}{S} 目的寄存器,源操作数 MVN R0,#0 ;将立即数0 取反传送到寄存器R0 中,完成后R0=-1 — CMP 比较指令 CMP{条件} 操作数1,操作数2 CMP R1,R0 ;将寄存器R1 的值与寄存器R0 的值相减,并根据结果设置CPSR 的标志位! g3 u4 r4 u8 o5 o& I/ p- z* ?
CMP R1,#100 ;将寄存器R1 的值与立即数100 相减,并根据结果设置CPSR 的标志位 — CMN 反值比较指令 CMN{条件} 操作数1,操作数2 CMN R1,R0 ;将寄存器R1 的值与寄存器R0 的值相加,并根据结果设置CPSR 的标志位
& S9 f0 ^) G: k* O; Q3 TCMN R1,#100 ;将寄存器R1 的值与立即数100 相加,并根据结果设置CPSR 的标志位 — TST 位测试指令 TST{条件} 操作数1,操作数2 TST R1,#%1 ;用于测试在寄存器R1 中是否设置了最低位(%表示二进制数). j. H8 Z0 W$ A% `# I
TST R1,#0xffe ;将寄存器R1 的值与立即数0xffe 按位与,并根据结果设置CPSR 的标志位 — TEQ 相等测试指令 TEQ{条件} 操作数1,操作数2 TEQ R1,R2 ;将寄存器R1 的值与寄存器R2 的值按位异或,并根据结果设置CPSR 的标志位 — ADD 加法指令 ADD{条件}{S} 目的寄存器,操作数1,操作数2 ADD R0,R1,R2 ; R0 = R1 + R2
6 i5 ~. B# a5 r2 I1 S( iADD R0,R1,#256 ; R0 = R1 + 256
9 N+ T; {, l7 O" S' M; n, i- {: G7 RADD R0,R2,R3,LSL#1 ; R0 = R2 + (R3 << 1) — ADC 带进位加法指令 ADC{条件}{S} 目的寄存器,操作数1,操作数2 ADDS R0,R4,R8 ; 加低端的字. z# ]3 W/ w7 s" ~& ^
ADCS R1,R5,R9 ; 加第二个字,带进位
+ T% t/ b8 G3 d' G4 ?& [) o( w' ?ADCS R2,R6,R10 ;加第三个字,带进位
* B2 _0 S& y1 S7 ZADC R3,R7,R11 ; 加第四个字,带进位 — SUB 减法指令 SUB{条件}{S} 目的寄存器,操作数1,操作数2 SUB R0,R1,R2 ; R0 = R1 - R2
9 ^/ h2 h4 Q' J1 L5 nSUB R0,R1,#256 ; R0 = R1 - 2567 a8 ^9 k+ W+ G( I& N6 E
SUB R0,R2,R3,LSL#1 ; R0 = R2 - (R3 << 1) — SBC 带借位减法指令 SBC{条件}{S} 目的寄存器,操作数1,操作数2 SUBS R0,R1,R2 ; R0 = R1 - R2 - !C,并根据结果设置CPSR 的进位标志位 — RSB 逆向减法指令 RSC{条件}{S} 目的寄存器,操作数1,操作数2 RSB R0,R1,R2 ; R0 = R2 – R1- l# m6 K' ~0 B" T
RSB R0,R1,#256 ; R0 = 256 – R1
) |, W4 \5 ^ K4 V& ^RSB R0,R2,R3,LSL#1 ; R0 = (R3 << 1) - R2 — RSC 带借位的逆向减法指令 RSC{条件}{S} 目的寄存器,操作数1,操作数2 RSC R0,R1,R2 ; R0 = R2 – R1 - !C — AND 逻辑与指令 AND{条件}{S} 目的寄存器,操作数1,操作数2 AND R0,R0,#3 ; 该指令保持R0 的0、1 位,其余位清零。 — ORR 逻辑或指令 ORR{条件}{S} 目的寄存器,操作数1,操作数2 ORR R0,R0,#3 ; 该指令设置R0 的0、1 位,其余位保持不变 — EOR 逻辑异或指令 EOR{条件}{S} 目的寄存器,操作数1,操作数2 EOR R0,R0,#3 ; 该指令反转R0 的0、1 位,其余位保持不变。 — BIC 位清除指令 BIC{条件}{S} 目的寄存器,操作数1,操作数2 BIC R0,R0,#%1011 ; 该指令清除 R0 中的位 0、1、和 3,其余的位保持不变。 3、乘法指令与乘加指令 ARM 微处理器支持的乘法指令与乘加指令共有6 条,可分为运算结果为32 位和运算结果为645 A) X0 Z! A/ F- A. N0 J) G4 a; t
位两类,与前面的数据处理指令不同,指令中的所有操作数、目的寄存器必须为通用寄存器,不能$ s+ \1 _8 Y l4 Z8 Q% F. t6 ?
对操作数使用立即数或被移位的寄存器,同时,目的寄存器和操作数1 必须是不同的寄存器。 乘法指令与乘加指令共有以下6 条: — MUL 32 位乘法指令 MUL{条件}{S} 目的寄存器,操作数1,操作数2 MUL R0,R1,R2 ;R0 = R1 × R2
. o3 O8 S' [1 g$ R6 H7 e) A, x8 SMULS R0,R1,R2 ;R0 = R1 × R2,同时设置CPSR 中的相关条件标志位 — MLA 32 位乘加指令 MLA{条件}{S} 目的寄存器,操作数1,操作数2,操作数3 MLA R0,R1,R2,R3 ;R0 = R1 × R2 + R3
5 t5 |& x( k9 B3 W: O& U) QMLAS R0,R1,R2,R3 ;R0 = R1 × R2 + R3,同时设置CPSR 中的相关条件标志位 — SMULL 64 位有符号数乘法指令 SMULL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2 SMULL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32 位9 E1 |9 Q1 \2 |* ?0 B5 L
;R1 = (R2 × R3)的高32 位 — SMLAL 64 位有符号数乘加指令 SMLAL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2
8 A9 ?$ C K( S; wSMLAL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32 位 + R0. X4 }: W5 }+ Y- ^4 v# u1 N* B
;R1 = (R2 × R3)的高32 位 + R1 — UMULL 64 位无符号数乘法指令 UMULL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2 UMULL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32 位; `* c9 Q' ~/ k- H) C
;R1 = (R2 × R3)的高32 位 — UMLAL 64 位无符号数乘加指令 UMLAL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2 UMLAL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32 位 + R0: o) D1 x( _- H
;R1 = (R2 × R3)的高32 位 + R1
; n1 { I, \7 V7 N' u9 d1 S2 S( Q4、程序状态寄存器访问指令 ARM 微处理器支持程序状态寄存器访问指令,用于在程序状态寄存器和通用寄存器之间传送
5 g5 x9 I1 x0 c( Q# \) R: s2 X数据,程序状态寄存器访问指令包括以下两条: — MRS 程序状态寄存器到通用寄存器的数据传送指令 MRS{条件} 通用寄存器,程序状态寄存器(CPSR 或SPSR) MRS R0,CPSR ;传送CPSR 的内容到R0
1 A0 z, _, s, |1 T7 s: fMRS R0,SPSR ;传送SPSR 的内容到R0 — MSR 通用寄存器到程序状态寄存器的数据传送指令 MSR{条件} 程序状态寄存器(CPSR 或SPSR)_<域>,操作数 MSR CPSR,R0 ;传送R0 的内容到CPSR) Q. ]! V4 t5 C, T2 m
MSR SPSR,R0 ;传送R0 的内容到SPSR
D- M8 l7 M7 A/ [" O; VMSR CPSR_c,R0 ;传送R0 的内容到SPSR,但仅仅修改CPSR 中的控制位域 5、加载/存储指令 ARM 微处理器支持加载/存储指令用于在寄存器和存储器之间传送数据,加载指令用于将存储
+ Y/ y Z& ]$ w0 }) n+ O器中的数据传送到寄存器,存储指令则完成相反的操作。常用的加载存储指令如下: — LDR 字数据加载指令 LDR{条件} 目的寄存器,<存储器地址> LDR R0,[R1] ;将存储器地址为R1 的字数据读入寄存器R0。
! B& e0 W, b5 g# D! M# hLDR R0,[R1,R2] ;将存储器地址为R1+R2 的字数据读入寄存器R0。8 q# _# h) Z& B5 D
LDR R0,[R1,#8] ;将存储器地址为R1+8 的字数据读入寄存器R0。
! ?$ |9 e+ `* R8 z' m0 ?LDR R0,[R1,R2] ! ;将存储器地址为R1+R2 的字数据读入寄存器R0,并将新地址R1+R2 写入R1。
9 ]7 I6 R: `$ |; FLDR R0,[R1,#8] ! ;将存储器地址为R1+8 的字数据读入寄存器R0,并将新地址R1+8 写入R1。/ ]1 m4 k0 H' V0 V9 W7 n$ W. W' K! u$ s: g8 a
LDR R0,[R1],R2 ;将存储器地址为R1 的字数据读入寄存器R0,并将新地址R1+R2 写入R1。! [( u! g+ f; S3 p, S6 t' L
LDR R0,[R1,R2,LSL#2]! ;将存储器地址为R1+R2×4 的字数据读入寄存器R0,并将新地址R1+R2×4 写入R1。9 O# Y( O, s$ R: j# q* G/ w w
LDR R0,[R1],R2,LSL#2 ;将存储器地址为R1 的字数据读入寄存器R0,并将新地址R1+R2×4 写入R1。 — LDRB 字节数据加载指令 LDR{条件}B 目的寄存器,<存储器地址> LDRB R0,[R1] ;将存储器地址为R1 的字节数据读入寄存器R0,并将R0 的高24 位清零。8 U" P7 F2 s$ V- S
LDRB R0,[R1,#8] ;将存储器地址为R1+8 的字节数据读入寄存器R0,并将R0 的高24 位清零。 — LDRH 半字数据加载指令 LDR{条件}H 目的寄存器,<存储器地址> LDRH R0,[R1] ;将存储器地址为R1 的半字数据读入寄存器R0,并将R0 的高16 位清零。
- r3 D7 a1 F0 d3 L0 {LDRH R0,[R1,#8] ;将存储器地址为R1+8 的半字数据读入寄存器R0,并将R0 的高16 位清零。# Q4 k* {& |* n9 t2 @. |- o* h, d
LDRH R0,[R1,R2] ;将存储器地址为R1+R2 的半字数据读入寄存器R0,并将R0 的高16 位清零。 — STR 字数据存储指令 STR{条件} 源寄存器,<存储器地址> STR R0,[R1],#8 ;将R0 中的字数据写入以R1 为地址的存储器中,并将新地址R1+8 写入R1。
8 F- I- {( l$ YSTR R0,[R1,#8] ;将R0 中的字数据写入以R1+8 为地址的存储器中。 — STRB 字节数据存储指令 STR{条件}B 源寄存器,<存储器地址> STRB R0,[R1] ;将寄存器R0 中的字节数据写入以R1 为地址的存储器中。' \ D0 h; D! v8 Y4 k
STRB R0,[R1,#8] ;将寄存器R0 中的字节数据写入以R1+8 为地址的存储器中。 — STRH 半字数据存储指令 STR{条件}H 源寄存器,<存储器地址> STRH R0,[R1] ;将寄存器R0 中的半字数据写入以R1 为地址的存储器中。
9 o- _9 t- B+ a6 y$ }' p* r: YSTRH R0,[R1,#8] ;将寄存器R0 中的半字数据写入以R1+8 为地址的存储器中。 6、批量数据加载/存储指令
( u; P' V* H7 O. W$ W4 V) i" M, m; w% p3 vARM 微处理器所支持批量数据加载/存储指令可以一次在一片连续的存储器单元和多个寄存器
8 q" B( N; P9 L5 }之间传送数据,批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器,批量数据存储 z* T2 ~8 h- r- b, R
指令则完成相反的操作。常用的加载存储指令如下:
— LDM 批量数据加载指令
8 y0 b: j3 C& ?, O9 Z8 U0 Y— STM 批量数据存储指令 LDM(或STM) 指令# f1 z# ]( v. {5 p7 C( t
LDM(或STM) 指令的格式为:
# [* X9 {5 ^: e6 b" aLDM(或STM) {条件}{类型} 基址寄存器{!},寄存器列表{∧}0 `3 c7 `7 x ^' E) n
LDM(或STM) 指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多个寄5 {: r. h6 d0 o# E; F- F8 Y
存器之间传送数据,该指令的常见用途是将多个寄存器的内容入栈或出栈。其中,{类型}为以下几种情况: IA 每次传送后地址加1;5 y. ~6 A4 ^; z O
IB 每次传送前地址加1;- J, y: j+ a3 j% Y% ?3 M" o6 Y7 l* N
DA 每次传送后地址减1;
4 k9 z2 w3 ?5 o- M+ l( K7 KDB 每次传送前地址减1;
% E6 p: l: j& h" o+ o0 u) V8 P; hFD 满递减堆栈;! ]! K/ k' X& {2 ~ Z
ED 空递减堆栈;7 k& O4 g1 l- u
FA 满递增堆栈;( V9 n. W+ n1 B. g
EA 空递增堆栈; {!}为可选后缀,若选用该后缀,则当数据传送完毕之后,将最后的地址写入基址寄存器,否5 @6 j; q" W# P$ D/ V
则基址寄存器的内容不改变。
: x7 u6 \8 H" q# H/ t# x) S: o基址寄存器不允许为R15,寄存器列表可以为R0~R15 的任意组合。 {∧}为可选后缀,当指令为LDM 且寄存器列表中包含R15,选用该后缀时表示:除了正常的数据" X2 @. b3 E" V6 [% l
传送之外,还将SPSR 复制到CPSR。同时,该后缀还表示传入或传出的是用户模式下的寄存器,而7 N/ L- X K% K7 g; R( o* b7 O
不是当前模式下的寄存器。 STMFD R13!,{R0,R4-R12,LR} ;将寄存器列表中的寄存器(R0,R4 到R12,LR)存入堆栈。
) u8 @" s% j; N ]9 N/ ^LDMFD R13!,{R0,R4-R12,PC} ;将堆栈内容恢复到寄存器(R0,R4 到R12,LR)。 7、数据交换指令 ARM 微处理器所支持数据交换指令能在存储器和寄存器之间交换数据。数据交换指令有如下$ Y- w5 y( c. l- W9 ?1 d* M
两条: — SWP 字数据交换指令 SWP{条件} 目的寄存器,源寄存器1,[源寄存器2] SWP R0,R1,[R2] ;将R2 所指向的存储器中的字数据传送到R0,同时将R1 中的字数据传; f! I0 ]/ ~7 G+ g$ ^/ {7 u6 C7 X
送到R2 所指向的存储单元。 {9 \! k! a2 D
SWP R0,R0,[R1] ;该指令完成将R1 所指向的存储器中的字数据与R0 中的字数据交换。 — SWPB 字节数据交换指令 SWP{条件}B 目的寄存器,源寄存器1,[源寄存器2] SWPB R0,R1,[R2] ;将R2 所指向的存储器中的字节数据传送到R0,R0 的高24 位清零,8 z( j! p, \$ h4 q) x- {. R
同时将R1 中的低8 位数据传送到R2 所指向的存储单元。
/ q4 f _, ^6 \6 v _SWPB R0,R0,[R1] ;该指令完成将R1 所指向的存储器中的字节数据与R0 中的低8 位数据0 r1 o5 C. m/ z9 S& |% }
交换。 8、移位指令 ARM 微处理器内嵌的桶型移位器(Barrel Shifter),支持数据的各种移位操作,移位操作在
; B/ T7 O! |; K' @% ~3 lARM 指令集中不作为单独的指令使用,它只能作为指令格式中是一个字段,在汇编语言中表示为指
3 ~4 p+ i% g: v; M: x- ?. a: w% Z令中的选项。例如,数据处理指令的第二个操作数为寄存器时,就可以加入移位操作选项对它进行
' O' ^, B1 X6 r( P ]" F! s各种移位操作。移位操作包括如下6 种类型,ASL 和LSL 是等价的,可以自由互换: — LSL 逻辑左移 通用寄存器,LSL(或ASL)操作数 MOV R0, R1, LSL#2 ;将R1 中的内容左移两位后传送到R0 中。 — LSR 逻辑右移 通用寄存器,LSR 操作数 MOV R0, R1, LSR#2 ;将R1 中的内容右移两位后传送到R0 中,左端用零来填充 — ASR 算术右移 通用寄存器,ASR 操作数 MOV R0, R1, ASR#2 ;将R1 中的内容右移两位后传送到R0 中,左端用第31 位的值来填充 — ASL 算术左移 通用寄存器,ASR 操作数 MOV R0, R1, ASL#2 ;将R1 中的内容右移两位后传送到R0 中,右端用第2 位的值来填充 — ROR 循环右移 通用寄存器,ROR 操作数 MOV R0, R1, ROR#2 ;将R1 中的内容循环右移两位后传送到R0 中。 — RRX 带扩展的循环右移 通用寄存器,RRX 操作数 MOV R0, R1, RRX#2 ;将R1 中的内容进行带扩展的循环右移两位后传送到R0 中。 9、协处理器指令 ARM 微处理器可支持多达16 个协处理器,用于各种协处理操作,在程序执行的过程中,每个! S6 i2 S" W* [9 v( b+ V% K5 M
协处理器只执行针对自身的协处理指令,忽略ARM 处理器和其他协处理器的指令。
; m0 b5 Q+ y) o; o; |1 |ARM 的协处理器指令主要用于ARM 处理器初始化ARM 协处理器的数据处理操作,以及在9 f: l( W9 ~+ o
ARM 处理器的寄存器和协处理器的寄存器之间传送数据,和在ARM 协处理器的寄存器和存储器之 k* s1 N% v) Z3 X- y$ ^% |1 n
间传送数据。 ARM 协处理器指令包括以下5 条: — CDP 协处理器数操作指令6 ^% b7 L+ W. P8 {* J3 ]' Y
— LDC 协处理器数据加载指令$ q# N0 F. }2 c7 z0 l
— STC 协处理器数据存储指令2 y8 E' E. ^. U
— MCR ARM 处理器寄存器到协处理器寄存器的数据传送指令/ J: ^6 y, P+ {1 q) J" U- T, T
— MRC 协处理器寄存器到ARM 处理器寄存器的数据传送指令 ---CDP 指令 CDP 指令的格式为: CDP{条件} 协处理器编码,协处理器操作码1,目的寄存器,源寄存器1,源寄存器2,协处理器操作码2。 CDP 指令用于ARM 处理器通知ARM 协处理器执行特定的操作,若协处理器不能成功完成特定的操
+ B7 F2 u" v2 w作,则产生未定义指令异常。其中协处理器操作码1 和协处理器操作码2 为协处理器将要执行的操 b( |; q5 U; w# J% m( p
作,目的寄存器和源寄存器均为协处理器的寄存器,指令不涉及ARM 处理器的寄存器和存储器。 指令示例: CDP P3,2,C12,C10,C3,4 ;该指令完成协处理器P3 的初始化 ---LDC 指令 LDC 指令的格式为: LDC{条件}{L} 协处理器编码,目的寄存器,[源寄存器] LDC 指令用于将源寄存器所指向的存储器中的字数据传送到目的寄存器中,若协处理器不能成功- S- k, U! `. S2 |: \
完成传送操作,则产生未定义指令异常。其中,{L}选项表示指令为长读取操作,如用于双精度数
! a3 \7 Z6 A+ M9 W; ?据的传输。 指令示例: LDC P3,C4,[R0] ;将ARM 处理器的寄存器R0 所指向的存储器中的字数据传送到协处理器P3 的寄存器C4 中。 ---STC 指令 STC 指令的格式为: STC{条件}{L} 协处理器编码,源寄存器,[目的寄存器] STC 指令用于将源寄存器中的字数据传送到目的寄存器所指向的存储器中,若协处理器不能成功3 y% V. ?- A7 X/ z. L# t
完成传送操作,则产生未定义指令异常。其中,{L}选项表示指令为长读取操作,如用于双精度数
b2 a$ W. w ]; X据的传输。 指令示例: STC P3,C4,[R0] ;将协处理器P3 的寄存器C4 中的字数据传送到ARM 处理器的寄存器R0 所指向的存储器中。 ---MCR 指令 MCR 指令的格式为: MCR{条件} 协处理器编码,协处理器操作码1,源寄存器,目的寄存器1,目的寄存器2,协处理器操作码2。 MCR 指令用于将ARM 处理器寄存器中的数据传送到协处理器寄存器中,若协处理器不能成功完成9 I, b; a7 Y& @* x. _% _2 y- C7 w
操作,则产生未定义指令异常。其中协处理器操作码1 和协处理器操作码2 为协处理器将要执行的9 q3 o& \/ m( T% ~1 R
操作,源寄存器为ARM 处理器的寄存器,目的寄存器1 和目的寄存器2 均为协处理器的寄存器。 指令示例: MCR P3,3,R0,C4,C5,6 ;该指令将ARM 处理器寄存器R0 中的数据传送到协处理器P3 的寄存器C4 和C5 中。 ---MRC 指令 MRC 指令的格式为: MRC{条件} 协处理器编码,协处理器操作码1,目的寄存器,源寄存器1,源寄存器2,协处理器操作码2。 MRC 指令用于将协处理器寄存器中的数据传送到ARM 处理器寄存器中,若协处理器不能成功完成2 F; v. ^& F3 T
操作,则产生未定义指令异常。其中协处理器操作码1 和协处理器操作码2 为协处理器将要执行的7 E; y1 L6 s. m& b, P
操作,目的寄存器为ARM 处理器的寄存器,源寄存器1 和源寄存器2 均为协处理器的寄存器。 指令示例: MRC P3,3,R0,C4,C5,6 ;该指令将协处理器P3 的寄存器中的数据传送到ARM 处理器寄存器 10、异常产生指令 ARM 微处理器所支持的异常指令有如下两条: — SWI 软件中断指令 / X3 I, x0 |$ z1 o7 t9 k8 i
— BKPT 断点中断指令 ---SWI 指令 SWI 指令的格式为: SWI{条件} 24 位的立即数 SWI 指令用于产生软件中断,以便用户程序能调用操作系统的系统例程。操作系统在SWI 的异常7 N+ D; @& ~5 L+ D2 r x
处理程序中提供相应的系统服务,指令中24 位的立即数指定用户程序调用系统例程的类型,相关
5 v k' x4 s" U/ W9 u参数通过通用寄存器传递,当指令中24 位的立即数被忽略时,用户程序调用系统例程的类型由通
0 t2 I/ n, K" R4 h) [ u2 Y5 N& Q. P用寄存器R0 的内容决定,同时,参数通过其他通用寄存器传递。 指令示例: SWI 0x02 ;该指令调用操作系统编号位02 的系统例程。 ---BKPT 指令 BKPT 指令的格式为: BKPT 16 位的立即数 BKPT 指令产生软件断点中断,可用于程序的调试。 * F2 t: A3 ~/ U6 N# q# }2 H- i) s
注:关于立即数产生的方法:书上说是由8位常数循环右移偶数位得到的。具体的移法如下: 举例:0X3F0由0X3F循环右移2*14=28位得到。 1、0X3F=0b00111111=0b0000 0000 0011 1111(要换成32位的) 2、将0b0000 0000 0011 1111循环右移28位,得到0b0000 0011 1111 0000 3、得到的数转换成十六进制0X3F0
: u" _% E: w ^6 B. S4 J |