EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
3 N4 m. `, M! aLoad/Store内存访问指令 4 n3 U: Y8 G) A. E) N+ Q6 c
— LDR 字数据加载指令 — LDRB 字节数据加载指令 — LDRH 半字数据加载指令 — STR 字数据存储指令 — STRB 字节数据存储指令 — STRH 半字数据存储指令 2 | D9 P; l& r: N
- j( J% ~" y) l, b
数据处理指令
8 z' D Q1 V; y% o3 ?/ uMOV 数据传送指令,有效数字不能超过2位16进制(8位二进制),MOV r2,#0xf800合法,MOV r2,0x1510错误,执行后原数据丢失。 MVN 数据取反传送指令 ;取反的有效数字不能超过2位16进制(8位二进制),MVN r2,#0xf800合法,MVN r2,0x1510错误,执行后原数据丢失。 CMP 比较指令 — CMN 反值比较指令 — TST 位测试指令 — TEQ 相等测试指令 — ADD 加法指令 — ADC 带进位加法指令 — SUB 减法指令 — SBC 带借位减法指令 — RSB 逆向减法指令 — RSC 带借位的逆向减法指令 — AND 按位与指令 — ORR 按位或指令 — EOR 按位异或指令 — BIC 位清除指令 8 L( F7 h" l8 d3 j8 _% O+ c* X
" A( ^8 u, m0 b' @2 ^乘法与乘加指令 M m1 @; p0 P' o/ ^
— MUL 32位乘法指令 — MLA 32位乘加指令 — SMULL 64位有符号数乘法指令 — SMLAL 64位有符号数乘加指令 — UMULL 64位无符号数乘法指令 — UMLAL 64位无符号数乘加指令
; E" S$ d/ Y2 X/ l! n
5 {8 v' b2 D2 u) Y; }0 c状态寄存器访问指令 # M2 K$ `. r7 I) Z8 @+ b" X0 A
— MRS 程序状态寄存器到通用寄存器的数据传送指 — MSR 通用寄存器到程序状态寄存器的数据传送指令
' b1 x+ @' C; ^: a# F7 O) A% A0 O. j3 I& o# ?; G: M8 p; o! \
移位指令
0 H7 l1 z- w6 I* } — LSL 逻辑左移 — ASL 算术左移 — LSR 逻辑右移 — ASR 算术右移 — ROR 循环右移 — RRX 带扩展的循环右移 * \ D# f4 C/ A T8 k
, H2 ~; D: q1 \8 g, U( A0 ~9 ~ c
跳转指令
6 M1 k+ h* g8 E9 @$ Z5 a3 X; z — B 跳转指令 — BL 带返回的跳转指令 — BLX 带返回和状态切换的跳转指令 — BX 带状态切换的跳转指令 ! L2 ?# ?8 \* W1 z: N
& a! B% y N$ G/ L \8 j协处理器指令 / w( \; a$ D( ^/ ` C* q
— LDC 协处理器数据加载指令 — STC 协处理器数据存储指令 — MCR ARM处理器寄存器到协处理器寄存器的数据传送指令 — MRC 协处理器寄存器到ARM处理器寄存器的数据传送指令 — CDP 协处理器数操作指令 ! g8 a, Q* T/ X# u$ r' z6 a k( m
其他常用的伪指令 % g/ f( S$ m8 K- d+ |
— AREA
9 V0 P _1 ^% t5 h: v— ALIGN : @7 _$ W8 g4 x
— CODE16 、 CODE32 # J' r3 N) V8 e
— ENTRY
8 f5 t9 U' h2 z) b" u, A— END
0 E# g3 F7 U1 J4 o% ]! p* [- \— EQU ' ?7 @% Z, Z0 J, {! R+ g
— EXPORT (或 GLOBAL )
7 e6 q& i- j$ h. x0 o— IMPORT , ?, N, t2 p9 X/ K3 B; Q( Q1 z
— EXTERN * s2 [3 J# O. a0 g, i
— GET (或 INCLUDE )
, g$ B2 t/ z$ b5 C9 Z! `— INCBIN
& M6 s, z/ u: h' T9 a l— RN
$ j2 j& [! k5 [6 a' e2 D— ROUT
8 f% N( o1 K3 V+ Y1) ARM杂项伪指令 * V/ n% H G F5 J
1. ADR伪指令:小范围的地址读取伪指令。
4 J: {4 x h; ?3 r. p5 L$ c' C/ bADR指令将基于PC相对偏移的地址值读取到寄存器中。在汇编编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能。 + f7 i5 \% x: a9 p. {& F% h
指令格式:ADR{cond} register ,expr
4 F" M$ X: e+ q/ }0 J9 d: f Register 加载的寄存器 9 t# V2 R& g% g3 b3 P8 o' p
Expr 程序相对偏移或寄存器相对偏移的表达式 ) D& P/ E: u, g5 Z
非字对齐地址在-255~255字节范围内; & g5 L: V* H9 J' N' k
字对齐地址在-1020~1020字节范围内。 # `$ x: r5 g& V% q m$ f
举例: ! C5 q% V; Z& A* m
Start MOV R1,#10
) [) N- v: }; }$ K. N ADR R4,start ;相当于PC-10后赋值给R4 % f7 Q5 w, Q4 g7 p* f. V
2. ADRL指令:中等范围的地址读取伪指令。 ) F J* a$ x3 K3 ~8 L
ADRL指令将基于PC相对偏移的地址值或基于相对偏移的地址值读取到寄存器中,比ADR伪指令可读取更大范围的地址。在汇编编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现ADRL伪指令功能,则产生错误,编译失败。 - s x4 ]$ o) y& }
指令格式与ADR相同
0 x8 A% D+ t- [( e% R. e 非字对齐地址在64K字节范围内; 2 m* G$ e+ O0 L, ] t
字对齐地址在256K字节范围内。
7 a m! F. d5 }6 g' E( X 举例:
- h, ]/ r0 y( Z7 ^ Start MOV R1,#10 8 r" b! C2 D# b& G6 h) F; ~
ADR R4,start+6000 ;=>ADD R4,PC,#0xe800 ADD R4,R4,#0x254 $ u8 R% r# \( A: T, z' G' d% i5 u
3. LDR指令 大范围的地址读取伪指令
/ M5 B: Z, d$ KLDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。
+ R; k9 }6 {: ]1 H3 o7 h在汇编编译源程序时,LDR指令被编译器替换成一条合适的指令,若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入字池(内存),并使用一条程序相对偏移的LDR指令从文字池读出常量。 + e) i( Y v; p+ V/ g- g
指令格式:LDR {cond} register , = expr/label_expr / L% N' j' K- j8 X+ e
Expr 32位立即数
& U4 D, `' o! m6 c' o+ P7 ] Label_expr 基于PC的地址表达式或外部表达式
% \5 L0 R8 {! U( \4 d( o p举例 0 c0 n+ ?$ g# K: u7 C2 G
LDR R0,=0x123987 ;加载32位立即数
) q3 x# k1 i" o LDR R0,=DATA_BUF+60 ;加载DATA_BUF地址+60
0 c: ]0 D+ o) d% Y( E. ^0 q4. NOP指令 ( \0 A# o2 g9 s
NOP指令产生所需的ARM无操作代码。可以使用指令MOV R0,R0。NOP不能有条件使用。执行和不执行无操作指令是一样的,因而不需要有条件执行。ALU状态不受NOP影响。 7 S2 ?" Y4 W- |( x( ?# M: X) x
2) 符号定义( Symbol Definit年ion )伪指令
) @( E7 J) T$ ]# R9 }; l7 t符号定义伪指令用于定义 ARM 汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。 . U$ l1 C& p1 _
常见的符号定义伪指令有如下几种: * c K& K- H, J# n5 V/ v( H7 M
Ø 用于定义全局变量的 GBLA 、 GBLL 和 GBLS
! @# b- T; d: N9 D' v8 k9 N# `6 lØ 用于定义局部变量的 LCLA 、 LCLL 和 LCLS
% M/ [1 N& |0 U: _2 i; A; P J( wØ 用于对变量赋值的 SETA 、 SETL 、 SETS : s* l* a. A+ t2 n
Ø 为通用寄存器列表定义名称的 RLIST
5 ?$ R+ U8 U1 z* V( v9 c3 L: N1. GBLA、GBLL 和GBLS
: x) A# ]4 ?* {" U/ `' z语法格式: % R# W$ \6 f2 H m6 K. ~
GBLA ( GBLL 或 GBLS ) 全局变量名 ! M+ z7 R+ r/ x0 h- t+ u( G
GBLA 、 GBLL 和 GBLS 伪指令用于定义一个 ARM 程序中的全局变量,并将其初始化。其中:
; _* ^; m& k0 u* N2 qGBLA 伪指令用于定义一个全局的数字变量,并初始化为 0 ;
0 N4 p5 ~3 B# x( x4 R/ [" T/ yGBLL 伪指令用于定义一个全局的逻辑变量,并初始化为 F (假); ! K* r g/ U# {, d/ L3 f4 ~4 I! H
GBLS 伪指令用于定义一个全局的字符串变量,并初始化为空;
. Y7 y4 I1 y A& N+ L由于以上三条伪指令用于定义全局变量,因此在整个程序范围内变量名必须唯一。
7 [. Q' m z7 Z使用示例: 2 @% \6 z$ B! U
GBLA Test1 ;定义一个全局的数字变量,变量名为 Test1 2 H$ d; C0 Q3 |% ~4 k! O5 T
Test1 SETA 0xaa ;将该变量赋值为 0xaa
4 n$ o1 d5 u$ ~( BGBLL Test2 ;定义一个全局的逻辑变量,变量名为 Test2
* X$ O. r: o7 [6 fTest2 SETL {TRUE} ;将该变量赋值为真
5 V* w; H: ?7 |5 p8 ?GBLS Test3 ;定义一个全局的字符串变量,变量名为 Test3
6 e# O7 v/ U. p- J: Z2 Q, kTest3 SETS “ Testing ” ;将该变量赋值为 “ Testing ”
4 A. |4 m* g/ f" \; W2. LCLA、LCLL 和LCLS
* i/ B# z$ {. |7 v语法格式:
?1 d1 W- d" p! ]" Z4 ~# k1 S- dLCLA ( LCLL 或 LCLS ) 局部变量名 7 s) q7 M& a* x) E
LCLA 、 LCLL 和 LCLS 伪指令用于定义一个 ARM 程序中的局部变量,并将 其初始化。其中: % ~, b% v# M0 r
LCLA 伪指令用于定义一个局部的数字变量,并初始化为 0 ; 8 `" d$ ~9 X) a% h; d7 b3 b! h+ j) i
LCLL 伪指令用于定义一个局部的逻辑变量,并初始化为 F (假);
" d' |; s- m6 I: ~1 X# I! k, ^LCLS 伪指令用于定义一个局部的字符串变量,并初始化为空;
8 ~* i1 T. `% g7 ?* s2 B: N* ~以上三条伪指令用于声明局部变量,在其作用范围内变量名必须唯一。
/ l+ Z# r$ j+ f; W o: h7 a使用示例: & M! t: } d& P; l# E7 X. m" a
LCLA Test4 ;声明一个局部的数字变量,变量名为 Test4
0 x6 J/ L9 O) m" o9 D; p' tTest3 SETA 0xaa ;将该变量赋值为 0xaa
- d+ v Z3 ~6 w5 n% {7 x+ ~' v+ DLCLL Test5 ;声明一个局部的逻辑变量,变量名为 Test5 : K; L4 F$ S, e7 g* Z# o) }
Test4 SETL {TRUE} ;将该变量赋值为真 0 o; R. b6 o" V4 |
LCLS Test6 ;定义一个局部的字符串变量,变量名为 Test6 % w. w$ N! M1 {
Test6 SETS “ Testing ” ;将该变量赋值为 “ Testing ” 4 |" m3 r, R/ q( P+ u
3. SETA、SETL 和SETS
) k: _ i% y% a语法格式:
7 O& w0 I% I( w变量名 SETA ( SETL 或 SETS ) 表达式
# ], K* v: x& D6 v* B0 \伪指令 SETA、SETL、SETS用于给一个已经定义的全局变量或局部变量赋值。
6 n6 C) u6 @( Y. d& r. P$ USETA 伪指令用于给一个数学变量赋值;
- E) P! i, W/ @. l* i. \" i3 ^SETL 伪指令用于给一个逻辑变量赋值; ! y" O4 e5 S! ^7 _5 d3 Z" W# Z
SETS 伪指令用于给一个字符串变量赋值; : W& `7 S5 [4 C3 x! d# c8 { P
其中,变量名为已经定义过的全局变量或局部变量,表达式为将要赋给变量的值。
; m; A9 G, v8 t2 m; ?2 B0 Q% ]使用示例: T% J6 A) C q8 R2 \5 F, W! j
LCLA Test3 ;声明一个局部的数字变量,变量名为 Test3
! { _; H2 v p- r# P1 o, Z! |Test3 SETA 0xaa ;将该变量赋值为 0xaa + ]* W: [' {2 V
LCLL Test4 ;声明一个局部的逻辑变量,变量名为 Test4
, p6 s3 `/ _& O! F& F! QTest4 SETL {TRUE} ;将该变量赋值为真 5 Q+ z# {. } L+ r
4. RLIST
+ m$ Y' \* i5 O2 @# P语法格式: 3 c \ f, _4 ~! k5 q6 {5 x
名称 RLIST { 寄存器列表 }
6 S# f( u9 U0 u8 zRLIST 伪指令可用于对一个通用寄存器列表定义名称,使用该伪指令定义的名称可在 ARM 指令 LDM/STM 中使用。在 LDM/STM 指令中,列表中的寄存器访问次序为根据寄存器的编号由低到高,而与列表中的寄存器排列次序无关。 * @" O% q y) `' n
使用示例:
e" }9 j3 F& Q% K6 oRegList RLIST {R0-R5 , R8 , R10} ;将寄存器列表名称定义为 RegList ,可在 ARM 指令 LDM/STM中通过该名称访问寄存器列表。
8 L i& V" z/ V7 ^# O6 R3) 数据定义( Data Definition )伪指令 3 s s! w9 ~$ Y) b
数据定义伪指令一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。 ; t% N5 N- Q8 M4 q3 m
常见的数据定义伪指令有如下几种: : q) E, Y# [% ]$ d4 n) A! ~
— DCB 用于分配一片连续的字节存储单元并用指定的数据初始化。 - S+ O, e) q4 f; J* [- ^; H: e, w0 t
— DCW (DCWU) 用于分配一片连续的半字存储单元并用指定的数据初始化。
7 W- ]: u1 |, ]) K— DCD (DCDU) 用于分配一片连续的字存储单元并用指定的数据初始化。 1 J; \9 _6 L P& n! g3 \/ A. ?
— DCFD (DCFDU)用于为双精度的浮点数分配一片连续的字存储单元并用指 定的数据初始化。
( s' |6 W0 h8 l* {! {% [— DCFS DCFSU) 用于为单精度的浮点数分配一片连续的字存储单元
9 t3 M) H# _2 p2 |, s( Q& ]* _: ?9 Z0 W! g- \
|