EDA365电子论坛网
标题:
ARM之ARM汇编
[打印本页]
作者:
piday123
时间:
2021-4-28 11:00
标题:
ARM之ARM汇编
+ ^4 I) P0 {: n* \
一、指令和伪指令
! R+ r6 n7 g4 g! _$ D8 [
, b& o( \1 o; h5 B3 S
汇编指令是CPU机器指令的助记符,经过编译后会得到一串10组成的机器码,可以
; I( ?& A& N' ~( F; r' j; _% j- y
, P( ?2 t ?* x% F* a2 W' X& J
由CPU读取执行。
. l& \; }# ~4 n9 V! ]4 b$ }* n
; R" C' `( X: Q- B
汇编伪指令本质上不是指令(只是和指令一起写在代码中),它是编译器环境提供
, w* k3 @' a& f) B0 J; r. J* [
) z: o! K& G1 m* b1 S' A7 h! B) z
的,目的是用来指导编译过程,经过编译后伪指令不会生成机器码。
9 K6 t- C: _( q/ A: y! M; v/ a: J
' L9 ]% {6 g: Y8 v3 W
二、两种不同风格的ARM指令
! J+ [1 t( T! G+ m3 F
+ p! u0 [: f* J9 ~+ u4 M& e$ l
1、ARM官方的ARM汇编风格:指令一般用的小、windows中IDE开发环境如:LDR
R; `& Z! E# J. p$ l: `
0 r3 s0 z4 F) A Q0 R
R0,[R1]
4 R% V/ ?9 j/ R R6 [
5 b) r0 ? ]# s/ \. w* b
2、GNU风格的ARM汇编:指令一般用小写字母、linux中常用。如:ldr r0,[r1]
9 b7 r( j1 `, F7 F$ {9 Z
: U. M, U1 w) S/ r) M
三、ARM汇编的特点
Z l7 r1 s; v
' y1 D/ [" {3 B4 ?# x" x7 F( Z
1、LDR/STR架构
2 z$ P: e: y) M0 e& `" G+ _; g& v6 U
7 }" b! P$ l; L, L- a' n
(1)、ARM采用RISC架构,CPU本身不能直接读取内存,需要将内存中的值加载
" }/ Q/ c8 _ ^+ ~2 \' e) T. a
, n G% t+ \# x) ~
到通用寄存器中才能被CPU处理。
& |7 Y7 Q/ F' p |
) D4 L; B' j4 x- w
(2)、ldr指令将内存内容加载入通用寄存器。
: A, N6 u& V/ R1 ^6 s. E
3 O8 e2 ]$ _9 ~. y& r; j2 V
(3)、str指令将寄存器中的值加载到内存空间中。
; c; A/ g# n0 w+ q
! R: l$ a* R: R
(4)、ldr/str组合用来实现ARM CPU和内存数据交换。
1 M0 b- \- A# N/ [' y; v
. [7 ~& j+ ]4 ^: P
2、ARM汇编特点:多级流水线
3 z5 u" G, y! J
9 U" z- G; I- B
-
1.png
(100.76 KB, 下载次数: 2)
下载附件
保存到相册
2021-4-28 10:59 上传
: e3 o! |' }' A* a& E( F6 X
+ J& f- _! q" J2 [) T9 w
3、8中寻址方式
2 Y$ L: a( s( Y9 {( }' R, M0 X, B
* T0 o9 }, q2 o u; L
寄存器寻址 mov r1,r2
- t- X( M3 d) B" _8 j
) @9 g3 E; h6 S2 p5 R& F9 j
立即寻址 mov r0,#0xFF00
* a* u! H/ V# b) E! H
! s; ^5 E" \* G, X( M
寄存器移位寻址 mov r0,r1,lsl#3
" S6 d: n' {0 b
! R! \" @3 J3 B" w9 W; ^5 m1 a
寄存器间接寻址 ldr r1,[r2]
1 d5 q+ x2 _( A! |6 A
- T ^0 E+ F& ^+ k L* U5 [0 o
基址变址寻址 ldr r1,[r2,#4]
1 m* [( }* @ m7 c
% k4 \' f5 u, ~ [ O* ~4 c( X
多寄存器寻址 ldmia r1!,{r2-r7,r12}
) A) W( ^. F8 f4 j1 Z3 f
, G+ Z6 `) E, j5 Z8 E' @7 Q% g# b+ \
堆栈寻址 stmfd sp!,{r2-r7,lr}
" o2 j% G$ X" k# I
2 L% O0 q) }# s8 |
相对寻址 beq flag
$ Y y$ ?& e9 u% G7 W
1 @% R8 q2 e* O s9 r3 {, {
flag:
$ Z# _9 c# h8 u! T! e" N
, e* R& {& ~: ?: @* {
四、ARM常用的汇编指令:
0 f, X% w& i! ]6 c$ P/ w9 f
. e% W: a$ m, w6 {
数据传输指令:mov mvn
) y: q# o) M/ y0 d% N
* J4 ^8 A1 J% j# t- f0 w+ K
算术指令: add sub rsb adc sbc rsc
) I: G; P3 u. {
* u) ]3 G: S# W/ Q
逻辑指令: and orr eor bic
5 J4 T7 D) u% y* v
: h7 ^6 Z y2 I7 b Z) Q$ w
比较指令: cmp cmn tst teq
) A* M- Y9 z8 G& \" n2 F# g+ B
4 s% h+ i! M! D, J! F- X
乘法指令: mvl mla umull umlal smull smlal
$ _/ h2 X6 d( i K @4 Y* _ R ~
' i+ w& M: a8 e0 F# R
前导零计数器 :clz
q( m: H7 w% X+ {8 _* o) g) j: t$ k
, b ^+ I9 t- g) K% @
CPSR寄存器比较特殊,需要专门的指令访问:这就是mrs和msr
9 x" ~- `( Y% G/ Y N/ j3 N
* X7 v `6 J# ^/ v& U
mrs用来读取CPSR的值,msr用来写CPSR
0 o$ z, @' z( y# O4 V! ]1 j
; T/ O) C6 `& _, c6 o# n1 _! C
协处理器cp15操作指令
) W% V' T. X- @* g
* S% g9 ?: g+ S" o1 n
mrc用来读取cp15中的寄存器,mcr用来写入cp15中的寄存器
# k8 M8 O3 s, p) U: X+ r
& j3 b r1 O6 Y L9 Q
^的作用:在目标寄存器有pc时,会同时将spsr写入到cpsr中,一般用于从异常模式返回。
" a1 _2 B, o& u4 ]. r
6 q, v4 P$ J2 X! j
例如 ldmfd sp!,{r0-r6,pc}^
9 ?* T4 M8 a8 Q3 u2 L# r# C; r
( G9 W' u. K( W* ~
五、伪指令
) F) t h% {' ^) Z, j% j5 K
! {2 G v9 z+ m2 w' \9 H
1、伪指令不是指令,伪指令和指令的根本区别是经过编译后会不会生成机器码。
8 N1 ]. g O4 Y5 Z M; F9 J
: y4 ~* |' U3 w$ ]9 V
2、伪指令的意义在于指导编译过程。
# u3 U6 f# @+ |+ ^$ z1 G
! u! y3 u* B% G- x% ?% l1 E; f
3、伪指令是和具体的编译器相关的,我们使用gnu工具链,因此学习gnu环境下的汇编伪指令。
7 F6 F6 e7 g# I) h! h5 ~0 x- ~
( ?+ _+ D* w9 x
4、@用来做注释。和C语言中的//是相同的。
% @0 W' x* `& w$ L, O6 `; t2 g& c
; q5 j' S1 q( c/ j
5、#做注释,一般放在行首,表示这一行都是注释而不是代码
- L k* h- u7 h4 d3 \5 g+ b. k) _
4 L- ~! U8 ^6 x
6、:以冒号结尾的是标号
: r) r5 w. l# K# q6 I3 T- K/ U1 I
0 O, }, `" S) ^; ^5 S* e
6、.点号在gnu汇编中表示当前指令的地址
0 @+ P+ S# s0 q. F5 ^4 x* O5 E+ M
" n$ s) ~- U1 R8 l* I5 M
7、#立即数,前面要加#或者$
3 X8 R. e ?. u$ J; S; }
. [2 B( j& i7 S' T
8、 重要的几个伪指令:
, i3 N* ^6 r; s% o8 M, z- X5 N$ M
4 m5 W5 k1 Z! k) C/ b( ~, z/ r
ldr 大范围的地址加载指令
: X9 J8 E: \% B1 t5 M/ N+ `
o& E6 V; N/ ^1 O- l7 I* F' Y$ w
adr 小范围的地址加载指令
3 Z! F) f$ R$ a" l# I: t8 i+ |
7 X( @0 Y5 J7 |; P8 T" x
adrl 中等范围的地址加载指令
0 J' G; @+ @% _! V2 S
2 o' ?: [- K" R+ @' ]0 S
nop 空操作
: E u, C) B" j2 Y6 [9 E+ k
# m0 Y8 A5 r- C/ |* b
9、adr和ldr
# @8 n# ^! B1 N. P- R
1 q+ j1 ]( {% P! e A0 U: u
adr编译时会被1条sub或者add指令替代,而ldr编译时会被一条mov指令替代或者文字池处理。
8 L( E" i: W- R3 b# h2 }) H
# f# b) y8 L( n j* Z2 L; N4 Q$ x) r
adr总是以pc为基准来表示地址,因此指令本身和运行地址有关,可以用来检测当前运行地址在
: T& i8 u9 E& [% N
7 {7 G$ U7 Q. L: M
哪里。
* g4 B5 D+ V; r- H" z- b6 _/ b
( V3 S( t; g. ^$ @+ x4 J, q% H
ldr加载的地址和链接时给定的地址有关,由链接脚本决定。
( f% d5 [- r! m5 n% ^
6 @! J) q5 N" p9 l- S( j/ z( X
欢迎各位指出不足之处
2 b# f, D! O, e& _
1 w+ G" i: E) p
作者:
xiaogegepcb
时间:
2021-4-28 13:11
ARM汇编
欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/)
Powered by Discuz! X3.2