找回密码
 注册
关于网站域名变更的通知
查看: 554|回复: 1
打印 上一主题 下一主题

ARM之ARM汇编

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2021-4-28 11:00 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
  B  T8 ]& r% m2 i* M2 C/ ^
一、指令和伪指令8 t) a& L# b: z$ j0 [! ?/ T- V+ H! o

6 H4 z/ r2 p0 `* C$ I+ n    汇编指令是CPU机器指令的助记符,经过编译后会得到一串10组成的机器码,可以) u2 ~* D( U: Y$ }3 b
, d. z! b4 Z9 Y, R- Y6 u# b. b& \) z
    由CPU读取执行。
% F& ^9 G/ f! N9 d1 r6 ^7 \) D7 H7 G- \4 b; D) e$ [0 n+ B, }3 w
    汇编伪指令本质上不是指令(只是和指令一起写在代码中),它是编译器环境提供& m( J/ [! ~7 c4 R% q& j
1 @' `1 {! t. n5 m
    的,目的是用来指导编译过程,经过编译后伪指令不会生成机器码。
: \0 i" P4 L6 L% [: z! {9 a7 a: [: R. T! \- Z) g. S
二、两种不同风格的ARM指令. ?' w  u+ {7 \. U( a; P
) p7 J1 o! N. k
    1、ARM官方的ARM汇编风格:指令一般用的小、windows中IDE开发环境如:LDR' M5 |' J5 e/ g2 u( M; m

2 o% F3 e  J$ l        R0,[R1]0 R, V5 I' J3 k$ L- F( j6 i

9 M& F+ z  o3 ?9 d* [4 t* g    2、GNU风格的ARM汇编:指令一般用小写字母、linux中常用。如:ldr r0,[r1]
/ p& a* w2 }; {, U2 e9 t. v4 e6 ?6 I1 R0 ^# v$ A6 ?/ C: W9 S
三、ARM汇编的特点* e4 Z- C0 x4 A# Y8 K. ^/ y
; W6 F" J+ A3 U6 q  A4 z( z2 N5 O0 F
    1、LDR/STR架构$ U" v" P( v: z# K

6 h0 W$ I. j% f' a        (1)、ARM采用RISC架构,CPU本身不能直接读取内存,需要将内存中的值加载6 `  }' w4 A4 R7 K

7 t. I! h4 U9 C/ X5 C; P            到通用寄存器中才能被CPU处理。: X7 u7 ]/ M% I2 D! R

+ G' u$ L+ ]/ K( ^$ M        (2)、ldr指令将内存内容加载入通用寄存器。
3 S4 t2 }+ C) L
! k2 ]4 C  j6 l! ^7 D) j        (3)、str指令将寄存器中的值加载到内存空间中。8 u8 H8 e, A% N2 Z5 ?
! S8 N; u9 v5 G8 {( J
        (4)、ldr/str组合用来实现ARM CPU和内存数据交换。
/ x% ]& D$ e) N' a# Y% I
* A* Y) c* J- _% y0 m1 H    2、ARM汇编特点:多级流水线
8 X, ~. d' b' U0 n
' y; U. T. e; P        - , u6 n" w; z2 f: a
: R5 j7 M/ Q6 H$ m( ]7 F, D' ]
    3、8中寻址方式- V4 G' W$ ]3 v! l
; s  U( u' v/ Y! T% W
        寄存器寻址               mov r1,r2' S8 O& N9 _! ~% A* _$ z4 s) y

6 i' o7 g3 {, y0 w7 Z! C  Q: y8 h        立即寻址                  mov r0,#0xFF00
4 r( Q! L* x3 ^+ G' w7 n7 w% }3 ^6 e' ^
        寄存器移位寻址        mov r0,r1,lsl#3$ r. f2 u6 ?7 [+ C; A7 P2 L5 x- d7 h

. a, E4 [/ _  h' p- a! i' U$ P        寄存器间接寻址        ldr r1,[r2]" C6 v) s% W0 U$ ?" U2 C" W& G

% n5 f: O+ I5 s- {        基址变址寻址           ldr r1,[r2,#4]% F) a4 K' `) @% Z
  L5 n! ~% t5 q
        多寄存器寻址          ldmia r1!,{r2-r7,r12}
3 N- g5 B& A3 k6 |0 p3 L, T: x% S5 c* [6 ^: A  O: I
        堆栈寻址                 stmfd sp!,{r2-r7,lr}
2 O/ ^4 y; Y/ @- \% i% |
! o) f: @2 H  T' Z9 n        相对寻址                         beq flag
4 H/ K" U* ^; U! C5 Z, L! ]9 j
4 U  O# ~3 Q# B                                        flag:. l3 n# f4 s: U% U; [# j

/ a3 X5 E- m0 f6 |6 V四、ARM常用的汇编指令:# P2 f# K6 a4 x

2 x; v8 d0 o) l- F+ h8 q" y5 B        数据传输指令:mov mvn7 M; i* u* I3 z! q6 Z. t4 b% f5 x
* U4 ~- @' f& p- ~" O
        算术指令:    add sub rsb adc sbc rsc$ _7 k# ?! g. C3 ~+ V( D) |4 M
2 u$ i4 c! j! M3 T. W+ W
        逻辑指令:    and orr eor bic
8 q6 g/ C7 H4 B; D6 j0 `" Y9 a6 }
& K- E( z2 U7 L" _        比较指令:    cmp cmn tst teq+ d+ ^( [9 x) S" r+ a4 Q8 a0 @
( v8 W1 E8 `8 K6 b
        乘法指令:    mvl mla umull umlal smull smlal# ~7 r) L" T3 J# V, \

  _, }: ~3 @+ H  t, D1 N* i/ j        前导零计数器 :clz
! Q% X/ W1 b* {3 X
( O; P6 j1 ?5 i8 s8 o' }0 G        CPSR寄存器比较特殊,需要专门的指令访问:这就是mrs和msr
* F$ }% t& ~$ i) O# L$ C3 ?3 B4 z# O. g& x% S* [- [4 q6 E) f
            mrs用来读取CPSR的值,msr用来写CPSR
: i' A, \& f- `6 p7 o$ N$ `$ _0 t2 D0 V: U& _( x2 n3 T: }
        协处理器cp15操作指令
6 m) M) K8 A0 D( v" {# Y
( M( ^5 S! J! k# }) m            mrc用来读取cp15中的寄存器,mcr用来写入cp15中的寄存器
) q, M  `  w* X* ?8 ~7 O# x% k' b( V' {; u+ p
       ^的作用:在目标寄存器有pc时,会同时将spsr写入到cpsr中,一般用于从异常模式返回。
* c, `1 ^8 I) y' q
9 ?+ w$ S! a. E+ B        例如 ldmfd sp!,{r0-r6,pc}^
% }4 l/ A! _( ?5 r# Y$ T$ f7 y( M/ \7 }7 ^( ^! G" t7 U- R
五、伪指令
2 i& \' r  B4 h& C* l( q9 f0 ?9 |. |2 }* {, h) N3 Q
    1、伪指令不是指令,伪指令和指令的根本区别是经过编译后会不会生成机器码。5 Y* X) V6 f: h# W6 `, o* o

) {3 e; D1 F7 k3 X    2、伪指令的意义在于指导编译过程。" _$ K# H3 n# v

  V* k' z7 a, O    3、伪指令是和具体的编译器相关的,我们使用gnu工具链,因此学习gnu环境下的汇编伪指令。' I2 [% ~2 X* `

8 t3 K) a8 B7 B9 Q: h. l4 [    4、@用来做注释。和C语言中的//是相同的。- f0 P2 X8 ]7 R8 q+ w

# r0 }4 c- R4 A) _    5、#做注释,一般放在行首,表示这一行都是注释而不是代码# u: ^* n- m( S0 O2 r

) H  B8 @/ o2 y( w    6、:以冒号结尾的是标号
& N( {" ^4 l# p4 p& X3 G2 y# e% p* a9 R
    6、.点号在gnu汇编中表示当前指令的地址, e0 `8 B6 T7 i  @# H$ ^4 }  G

/ P! \. B4 k% \0 ^( A) C5 [" f, R    7、#立即数,前面要加#或者$
  l1 y  h9 [# k7 K" g9 L  N. K2 o' l1 a6 B7 E4 D1 _
    8、 重要的几个伪指令:
6 o; u% ^4 g; h$ G% E  D- W
7 D) v# A; A/ N" V0 ^4 k, Y- K/ B        ldr    大范围的地址加载指令
- h  S) X& z& \7 s" V+ Z/ F: e
; a' E7 ]8 J2 n        adr 小范围的地址加载指令% G( h" ?1 D( n9 O
. P* r; P' D/ m& a7 }) `3 V
        adrl 中等范围的地址加载指令
2 s0 ~  D  p. v  E2 u5 o* v* x& _7 k
        nop 空操作/ Q, v) r5 Y. R: O7 U" d9 o6 |

+ B. o& r' W1 ^% y    9、adr和ldr " A! O% x4 y. d+ R

7 R1 R1 b: u0 ]" ]- F        adr编译时会被1条sub或者add指令替代,而ldr编译时会被一条mov指令替代或者文字池处理。
, C5 d( l& _* G: w; U
* h0 W; @6 Q  z$ w$ P        adr总是以pc为基准来表示地址,因此指令本身和运行地址有关,可以用来检测当前运行地址在
/ Z3 r1 U5 y7 ^' `6 U
6 o9 q. a3 W, l* S        哪里。; B6 x9 Y6 W, p$ Y2 Q, p

/ J7 M( m$ u" W# N* P8 ~9 `        ldr加载的地址和链接时给定的地址有关,由链接脚本决定。
; ?; c2 K7 v% d- h! R$ `& r! [( t
    欢迎各位指出不足之处
. J: M' h; e7 {6 i4 I. `8 \% b# d# N% e. y0 I8 F2 t
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-24 07:15 , Processed in 0.156250 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表