|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 行者~ABC 于 2021-1-7 10:05 编辑
: ]( ~6 @- V1 l' Z
6 L& j6 t2 ~5 s- k2 l8 ]0 R
|6 H: F1 ]$ W% v, J* ~ARM Cortex-M4 支持的指令在下表 1~8 中列出。
" D8 [- ]' _! R p% `% P* v& K. ~0 B, P, H
表 1 16 位数据操作指令3 R# |; [4 p& S! V# D
指令 功能
3 Q/ m% B3 \6 @6 B% r d ADC 带进位加法: M+ H6 q. s1 B/ V C3 P
ADD 加法# |; z* B. o/ U- }1 q
AND 按位与。这里的按位与和 C 的”&”功能相同- d( S& c7 q7 i! _3 a' [0 s
ASR 算术右移. Z; h" J3 l9 j& {
BIC 按位清 0(把一个数跟另一个无符号数的反码按位与)* I( \* ~- h. g: i
CMN 负向比较(把一个数跟另一个数据的二进制补码相比较)* u/ o! d5 Y ^' f' _5 s
CMP 比较(比较两个数并且更新标志)9 s2 c- d7 B5 E) N N5 `5 j
CPY 把一个寄存器的值拷贝到另一个寄存器中" W2 q2 r& B, E+ H- y
EOR 近位异或" o! i% F" O ?- c( `
LSL 逻辑左移(如无其它说明,所有移位操作都可以一次移动多格)
& v0 F4 L6 O9 v# W/ ~ LSR 逻辑右移
1 r" g) o) v$ \9 ?; _2 l$ C MOV 寄存器加载数据,既能用于寄存器间的传输,也能用于加载立即数
4 W% E$ e8 T( M' L* ] MUL 乘法
w3 A* e5 h( I+ } MVN 加载一个数的 NOT 值(取到逻辑反的值)
- v3 @( T: A) p NEG 取二进制补码
# m! L" r" E1 c3 g% A2 G* o ORR 按位或: X; B8 W3 o5 t: w6 r: Y
ROR 圆圈右移
$ t4 Y2 H. k) Z' H. G( p p SBC 带借位的减法/ ?6 O& O, h. G9 a( y9 R
SUB 减法& [, c7 ~& D2 k
TST 测试(执行按位与操作,并且根据结果更新 Z)# o" M4 R u9 f, t+ q' m& y' V
REV 在一个 32 位寄存器中反转字节序) }4 P2 i0 v1 r" J
REVH 把一个 32 位寄存器分成两个 16 位数,在每个 16 位数中反转字节序
6 |( B2 A6 ~& T4 r3 H" s REVSH 把一个 32 位寄存器的低 16 位半字进行字节反转,然后带符号扩展到 32 位
1 n8 {4 ~% N" Z SXTB 带符号扩展一个字节到 32 位
0 @/ L' J# I! D- M SXTH 带符号扩展一个半字到 32 位# T' P9 N, ^! l1 r
UXTB 无符号扩展一个字节到 32 位
9 N/ N% S; ]1 [ UXTH 无符号扩展一个半字到 32 位& U2 G B5 L/ D0 \9 w) H
v5 h+ E! \* w
表 2 16 位转移指令; j- N( M6 P0 A3 m! I& i' V$ F
指令 功能
( x5 u1 W8 m( k1 J$ J/ C9 `/ ^# X B 无条件转移) s- x! B9 W, L) q0 M, z
B<cond> 条件转移
6 e+ h! R; q% t b BL 转移并链接。用于呼叫一个子程序,返回地址被存储在 LR 中
" u. a8 | U. g* A5 X" @4 t BLX 使用立即数的 BLX 不要在 ARM Cortex-M4 中使用) i( x7 _" ^; n8 f' D8 \
CBZ 比较,如果结果为 0 就转移(只能跳到后面的指令)) Z& {" l H3 t: V, f2 l, d
CBNZ 比较,如果结果非 0 就转移(只能跳到后面的指令)2 @* `/ D9 J7 W3 R
IT If‐Then1 `- c6 ]3 {. |5 B: I9 e7 D
, v; b6 ]! e% j 表 3 16 位存储器数据传送指令
2 C. v+ o1 z; o$ F 指令 功能3 f$ ]& _9 B$ l+ s% Y
LDR 从存储器中加载字到一个寄存器中
7 d; F F2 F/ k, ~2 S) {. U; H" w LDRH 从存储器中加载半字到一个寄存器中# B: t: J) ~( O
LDRB 从存储器中加载字节到一个寄存器中
9 G. k/ r8 m5 G" T. Q2 K% j! d LDRSH 从存储器中加载半字,再经过带符号扩展后存储一个寄存器中
8 ^8 |; b& ~4 M) a- [/ Z$ [5 A LDRSB 从存储器中加载字节,再经过带符号扩展后存储一个寄存器中
# ~' J& c& k2 @/ U STR 把一个寄存器按字存储到存储器中
) j( X( C6 x( W) | STRH 把一个寄存器存器的低半字存储到存储器中
- k9 I) S$ o$ `+ x" y3 X STRB 把一个寄存器的低字节存储到存储器中; U) A7 l/ O: D2 S
LDMIA 加载多个字,并且在加载后自增基址寄存器$ q* b/ h9 R( l9 |) k' b# Q
STMIA 加载多个字,并且在加载后自增基址寄存器/ g+ E" c0 O9 w' \8 i/ a9 n
PUSH 压入多个寄存器到栈中
3 |8 T( V1 k$ P POP 从栈中弹出多个值到寄存器中
! W: M( ]* i6 a3 o! Q7 X% U. F) e 16 位数据传送指令没有任何新内容,因为它们是 Thumb 指令,在 v4T 时就已经固定下来了。6 E6 i% s- [+ S' [
# f/ |0 ~+ e7 j( t p! t6 c
指令 功能
4 X6 S2 C/ c5 F; i( l SVC 系统服务调用( O9 z2 p9 N1 {/ }$ r' @6 Q' H3 k
BKPT 断点指令。如果调试被使能,则进入调试状态(停机)。或者如果调试监视器异常被使能,则调用一个调试异常,否则调用一个 fault 异常
2 E7 M& D/ ^1 M NOP 无操作3 J1 b' K3 W& p: }. O
CPSIE 使能 PRIMASK(CPSIE i)/FAULTMASK(CPSIE f)——清 0 相应的位
7 o+ d1 A( F, H7 I2 y$ ? W3 _" H CPSID 除能 PRIMASK(CPSID i)/FAULTMASK(CPSID f)——置位相应的位
$ s! M+ c7 s; y; Y2 c1 C0 y7 {: b : O' D' E+ ?1 P! m4 D: u
表 4 其它 16 位指令
/ [; k7 X T0 \8 l 指令 功能
) C% Y" c5 w% s9 t) l, ~ ADC 带进位加法3 @5 O( C# D; j- l7 }
ADD 加法
: T- p2 L# F- q6 N ADDW 宽加法(可以加 12 位立即数), M) v; |* a4 c2 B
AND 按位与' u/ J( V5 O5 l* T$ |6 E2 ~8 U
ASR 算术右移
' U. K6 L! U8 Y$ d; d BIC 位清零(把一个数按位取反后,与另一个数逻辑与)
* g0 V3 y1 q ^2 t: Q/ @ BFC 位段清零
$ N/ _3 q y. V BFI 位段插入
2 h# l7 h( m: |$ _ CMN 负向比较(把一个数和另一个数的二进制补码比较,并更新标志位): @/ ?- t0 B3 @
CMP 比较两个数并更新标志位
; t8 a6 U) F2 Z8 A, c CLZ 计算前导零的数目
- c; K( D6 V( x $ R5 z# @: L- x% ~3 H6 }0 @4 N) v7 \
表 5 32 位数据操作指令
, x. @3 k6 W. e, O- b! v: B( h
: k. K# q) ^! K1 |7 E4 F: E EOR 按位异或/ a/ m" i. B. q p- Z2 _
LSL 逻辑左移
5 x* H! S/ F; l3 R. x LSR 逻辑右移( J" H, O4 G1 Y1 r
MLA 乘加; }1 y" o( v6 |
MLS 乘减( P2 j# n) ]$ `8 _/ o& i! X
MOVW 把 16 位立即数放到寄存器的底 16 位,高 16 位清 0" e5 N l1 s; \, m* `' ]6 Q; p
MOV 加载 16 位立即数到寄存器(其实汇编器会产生 MOVW)0 T5 g. M9 X, ?
MOVT 把 16 位立即数放到寄存器的高 16 位,低 16 位不影响
: ]' A( u @) p! B MVN 移动一个数的补码
% U* V6 I% c+ n8 K' r+ m MUL 乘法( M: ?. O/ ^9 R0 }
ORR 按位或
3 y$ Y' b7 H( C: c! _ ORN 把源操作数按位取反后,再执行按位或
" V8 P( O2 F& x3 L RBIT 位反转(把一个 32 位整数先用 2 进制表达,再旋转 180 度)
0 G/ r G6 y( M/ B" { REV 对一个 32 位整数做按字节反转
, `8 e) [& R- x0 P5 V% h REVH/ 对一个 32 位整数的高低半字都执行字节反转2 Q0 r& r( h* q% m
REV16 对一个 32 位整数的低半字执行字节反转,再带符号扩展成 32 位数
( |9 k9 Z+ {& X- y3 J$ D' u! M; R REVSH 圆圈右移
" L p5 I9 z6 U1 f: J" w ROR 带进位的逻辑右移一格(最高位用 C 填充,且不影响 C 的值)2 G3 O+ ~9 w( @1 Z5 L
RRX 从一个 32 位整数中提取任意的位段,并且带符号扩展成 32 位整数
3 w9 U( j6 F/ I e9 \9 D SFBX 带符号除法
- u7 ^# O. A2 ~; c8 V SDIV 带符号长乘加(两个带符号的 32 位整数相乘得到 64 位的带符号积,再把积
# P5 d! M, Z, H, f9 k; F6 I SMLAL 加到另一个带符号 64 位整数中)" H2 _% m% ]! c1 P# j: Q2 W: K3 s
SMULL 带符号长乘法(两个带符号的 32 位整数相乘得到 64 位的带符号积)
- y/ L. z& u2 Q7 L SSAT 带符号的饱和运算( R6 V& b+ F0 Z' H0 a9 w3 e
SBC 带借位的减法3 \- Q9 O" C6 h( ]. y
SUB 减法6 E: d5 W7 z( {/ ?- W& x/ q8 {
SUBW 宽减法,可以减 12 位立即数
. B* X0 d" _7 Z" t# x3 s SXTB 字节带符号扩展到 32 位数
5 w% d7 ~1 ^" U2 t" f& {: s6 j7 T% X TEQ 测试是否相等(对两个数执行异或,更新标志但不存储结果)& k, w1 p- v& q0 B: ~: k
TST 测试(对两个数执行按位与,更新 Z 标志但不存储结果)
0 p- Y9 Z/ Q1 K UBFX 无符号位段提取' v% m& R! {' S; h; N# \! M1 i
UDIV 无符号除法
8 [! G* c: L9 _" w" A UMLAL 无符号长乘加(两个无符号的 32 位整数相乘得到 64 位的无符号积,再把积加到另一个无符号 64 位整数中)( @$ u8 q% D! S' ?0 d
UMULL 无符号长乘法(两个无符号的 32 位整数相乘得到 64 位的无符号积)9 y8 i3 c9 ], `% [: m1 z$ F
USAT 无符号饱和操作(但是源操作数是带符号的)
+ t& a7 u0 A. E( v" c3 o5 Q" ? UXTB 字节被无符号扩展到 32 位(高 24 位清 0)
' O9 A3 |3 Y. o UXTH 半字被无符号扩展到 32 位(高 16 位清 0). a, t% f4 h5 G4 I" O, p9 Q' u
N0 }$ I( I: o- |1 M$ ~ 表 6 32 位存储器数据传送指令6 W5 c+ Y1 b9 N0 w; \) \5 ~. ?3 g. ^
LDRH 加载半字到寄存器
* N+ m9 r2 l& ~: w LDRSH 加载半字到寄存器,再带符号扩展到 32 位4 a0 C- ^" i8 \6 _
LDM 从一片连续的地址空间中加载多个字到若干寄存器
; S0 Q: l2 ~( w3 p LDRD 从连续的地址空间加载双字( 64 位整数)到 2 个寄存器
0 B2 W3 O/ Y' H- I STR 存储寄存器中的字$ C0 A6 q5 q1 x
STRB 存储寄存器中的低字节" }5 T4 B7 g3 C4 R, U1 G
STRH 存储寄存器中的低半字
Z+ O2 t# V$ T/ H0 h# K STM 存储若干寄存器中的字到一片连续的地址空间中+ r. r8 o! K8 d7 A' j. c. i$ I8 {
STRD 存储 2 个寄存器组成的双字到连续的地址空间中+ D- ^$ o5 \, a6 Y
PUSH 把若干寄存器的值压入堆栈中0 v! o: E6 ?! n q( c
POP 从堆栈中弹出若干的寄存器的值 ( g8 n( v8 i& A" K) y
表 7 32 位转移指令7 q5 [3 {- f0 @5 s X! Y
指令 功能 v! t' y: C; N! F2 x9 P9 H0 i# z( E5 W
B 无条件转移: s6 l" Q+ q+ F
BL 转移并连接( 调用子程序)2 @& {9 l" _( W( H
TBB 以字节为单位的查表转移。从一个字节数组中选一个 8 位前向跳转地址并转移
1 t, Y' E$ J- c; E( {4 d TBH 以半字为单位的查表转移。从一个半字数组中选一个 16 位前向跳转的地址并转移
; B" ` d2 f" _. q3 d - i/ g1 r4 q4 _3 p
表 8 其它 32 位指令
6 M* R7 q" l1 l 指令 功能
! |- l- ^7 \/ j& T" U l/ H LDREX 加载字到寄存器,并且在内核中标明一段地址进入了互斥访问状态: {* u- l2 @1 Y! B1 q" H
LDREXH 加载半字到寄存器,并且在内核中标明一段地址进入了互斥访问状态- F( Z2 r2 n) |$ B5 Z: M& G4 z
LDREXB 加载字节到寄存器,并且在内核中标明一段地址进入了互斥访问状态( N+ z5 e9 |6 w3 `* Q# e8 Y* W
STREX 检查将要写入的地址是否已进入了互斥访问状态,如果是则存储寄存器的字3 L3 k0 Q; W) b9 k9 g# q2 ]7 B
STREXH 检查将要写入的地址是否已进入了互斥访问状态,如果是则存储寄存器的半字
3 h T; A9 y% { STREXB 检查将要写入的地址是否已进入了互斥访问状态,如果是则存储寄存器的字节# D1 o- _* ]) {8 ]+ b( i# W! U/ l
CLREX 在本地的处理上清除互斥访问状态的标记(先前由 LDREX/LDREXH/LDREXB 做的标记)
- \! F5 Q3 O& ]# G MRS 加载特殊功能寄存器的值到通用寄存器" |/ j6 s( P6 |, Y5 M
MSR 存储通用寄存器的值到特殊功能寄存器
( h) c) U4 B# q NOP 无操作- `* `+ O r; H9 e x
SEV 发送事件
+ a$ K# T8 M+ x8 a, u WFE 休眠并且在发生事件时被唤醒 n: R4 i, C' D$ f% s1 _2 _
WFI 休眠并且在发生中断时被唤醒' E, l' H) w) U2 }
ISB 指令同步隔离(与流水线和 MPU 等有关)
4 c* o% v' o/ t+ @: g! k: | DSB 数据同步隔离(与流水线、 MPU 和 cache 等有关) DMB 数据存储隔离(与流水线、 MPU 和 cache 等有关) 1 P+ ]9 j, {; j8 ]# A
# _& n0 t& N, \2 C6 r* R# i
1 o9 ^/ ^+ F2 ?
|
|