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

ARM之ARM汇编

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
' {' Y: A2 A/ i3 ~) c7 d+ x
一、指令和伪指令; v4 k0 T2 v* X+ n1 [7 }
. `7 g+ l- p# A
    汇编指令是CPU机器指令的助记符,经过编译后会得到一串10组成的机器码,可以
& s* [! ~5 Q9 F5 L. [) [( |# X9 f
5 M8 V9 ]9 C' X9 s9 Z! S    由CPU读取执行。. S" `$ q! N( O% B

( d5 {! k0 `4 s* M3 |0 Z    汇编伪指令本质上不是指令(只是和指令一起写在代码中),它是编译器环境提供
: f" w  k! q: X' ?/ I2 G& k! ?, m) U2 F* h: S" V2 `2 @9 E$ y9 ^
    的,目的是用来指导编译过程,经过编译后伪指令不会生成机器码。  g/ H, m; L' Y. @; y& d9 Q
$ _6 d! B$ z1 a+ s
二、两种不同风格的ARM指令
. v" c$ U, E/ \. V& I/ J, `8 m& T6 U2 y; _  g
    1、ARM官方的ARM汇编风格:指令一般用的小、windows中IDE开发环境如:LDR
7 c( C$ [4 P. {% r
" o* L* _4 E. M6 k7 u* F4 A  o        R0,[R1]
+ @; f1 z) z5 @
3 H# J0 R: k" ]0 k    2、GNU风格的ARM汇编:指令一般用小写字母、linux中常用。如:ldr r0,[r1]2 O- c5 f) k' M7 _8 \0 Q
: d/ a7 b# a1 Q. _4 m" ^# Y
三、ARM汇编的特点. B+ M# n2 D; t, j, K% \3 w
9 D. l6 L1 Z- V) X% e: J! `
    1、LDR/STR架构$ N0 Z/ Q# V$ J) o  ~

+ _- l1 w$ N" L1 \        (1)、ARM采用RISC架构,CPU本身不能直接读取内存,需要将内存中的值加载. m5 m1 h7 c5 M$ d! x

- `. ~% ~. `; S1 F/ u8 H; z            到通用寄存器中才能被CPU处理。
+ k5 \$ I& H- r) A3 E. B- `
" }- Q$ b- k% M% N& R! P5 U+ L        (2)、ldr指令将内存内容加载入通用寄存器。
5 L) u. E" h' W' P1 ~1 I  S+ m. j& l& A
        (3)、str指令将寄存器中的值加载到内存空间中。
+ d' f9 w! q5 W1 E% i6 u. _
& z) N# P7 {( w. m0 |        (4)、ldr/str组合用来实现ARM CPU和内存数据交换。# _& Y. w4 c3 \" n

7 `. L* j& H9 M3 Y$ k6 Q7 _    2、ARM汇编特点:多级流水线( ^+ D- Q% z2 L7 n1 w
8 G" Y  v8 D" z1 ?
        -
. w& z! i$ d% U
3 s0 g) C( B: s4 _. H" k    3、8中寻址方式) q. \9 R8 @. U6 i9 v% w% ^; P
4 Q$ x8 |) S9 b* C- Z
        寄存器寻址               mov r1,r2
- s. i9 c' T. s7 x$ G
: G" C; B1 n& _, B  v* }( {2 c        立即寻址                  mov r0,#0xFF00 ) k% ^0 F+ I6 J
% z% x9 T1 q. B' a5 S: q
        寄存器移位寻址        mov r0,r1,lsl#3
8 [% ~) K  M7 a/ {& i
- o, o) y) r  N/ j, v1 C  C) n8 W        寄存器间接寻址        ldr r1,[r2]
8 V9 \1 z' ?+ Z3 C. e* ^8 C: T+ u! x$ J2 @* @, Y# O. h7 X$ K: j
        基址变址寻址           ldr r1,[r2,#4]  r$ ]3 q2 l2 U
2 E* o) ~4 G1 Q
        多寄存器寻址          ldmia r1!,{r2-r7,r12}
- z: |7 Z: [  B4 g
" m8 i5 H% h% [" L0 _9 y% V+ O        堆栈寻址                 stmfd sp!,{r2-r7,lr}
) |9 p- ?* ]  S& x: S" m1 k$ p7 @2 I& T# m( a
        相对寻址                         beq flag( Q6 S8 q( F; G* P: I# v" d
& u" k* I5 ?  y0 Z; b
                                        flag:
' n. |# h  A, L' ^! m+ c% {% g) h* q
3 v2 X8 y) U- Z+ z四、ARM常用的汇编指令:; t. a! R  y$ Y# i, T5 |4 D" b

. l* M4 k& X9 L5 E! K        数据传输指令:mov mvn
* q- @) D" D7 ~* G- g: v2 K: n) r/ f3 R* B  g! v* D7 v
        算术指令:    add sub rsb adc sbc rsc
' Y& O3 A+ J: c! _$ a
: q+ N/ n. X0 k$ p) D: K% i% ]! Y        逻辑指令:    and orr eor bic% _1 N1 f+ I. i# L0 k9 N1 \" `

' A* L5 G( |3 ~4 A        比较指令:    cmp cmn tst teq
  m5 E( h; Q% s
1 |0 |3 a& U6 i3 t+ ]* K0 z3 n$ `        乘法指令:    mvl mla umull umlal smull smlal# F/ ^8 }/ }  `7 b' T5 |. [

# s. J* ~! h# |# b7 h2 k+ u        前导零计数器 :clz  }, @* g. d  U( I0 O

+ r; g# f3 p: t# Z8 {* V9 X! J# Y        CPSR寄存器比较特殊,需要专门的指令访问:这就是mrs和msr
% w7 |/ q, S& ~- C* t5 i
3 C3 ~9 g, q8 Z) x            mrs用来读取CPSR的值,msr用来写CPSR6 Q. a: X. o% X8 D
+ m. N+ U  U3 F& D# O; m
        协处理器cp15操作指令3 g( ~- U9 p/ G" {# d9 B% ~$ d% V
" Q: x6 s" b" v. m
            mrc用来读取cp15中的寄存器,mcr用来写入cp15中的寄存器
& k& e+ R; t5 F/ {7 o/ A  v
7 L" l0 O1 d# j; p. K1 }7 X, u       ^的作用:在目标寄存器有pc时,会同时将spsr写入到cpsr中,一般用于从异常模式返回。
: j2 J7 K6 D4 ?" i: P& i4 \
1 i5 M" p2 S2 Q        例如 ldmfd sp!,{r0-r6,pc}^
% O6 m0 f" ~  m5 z- ?" {( R2 t
/ V/ ?3 e/ F' c: ?/ B) H# w五、伪指令4 R& Q# G  b- n: \% E
  y) o% I5 o1 v+ K7 @& Z3 ^
    1、伪指令不是指令,伪指令和指令的根本区别是经过编译后会不会生成机器码。6 F0 x9 y6 S: O1 U" ]) Q: i
( I' {0 y% p. W8 Z
    2、伪指令的意义在于指导编译过程。+ R% d1 }% r; o+ I# A( H
- W( Z8 _! s8 u1 }8 L+ j$ {4 {
    3、伪指令是和具体的编译器相关的,我们使用gnu工具链,因此学习gnu环境下的汇编伪指令。4 e# W( f. X5 a$ ?0 J7 c

. c/ J5 p6 X4 D. M* f  h' E- X4 h3 ^    4、@用来做注释。和C语言中的//是相同的。% E+ d! W' t3 {  n, T" x0 ?

4 b0 |$ g- {/ s( I& A# `& u    5、#做注释,一般放在行首,表示这一行都是注释而不是代码$ {+ Y2 |- @0 P* h

' q* ~0 H, r  ]    6、:以冒号结尾的是标号( {( H4 X; i: J# p' x% X

" |; B. |2 T- C3 h8 T: g, v5 E; P1 s    6、.点号在gnu汇编中表示当前指令的地址2 R1 E  z7 r( g' I& V

7 z' T6 Q4 O8 B9 x    7、#立即数,前面要加#或者$
0 v5 M6 X& u2 D" w# A- i$ c) P' ~/ P# `" N6 S: z& S& U
    8、 重要的几个伪指令:
; g( `9 w; q# e$ x" _, A+ l  M9 }. E; O; W$ a/ Y8 i
        ldr    大范围的地址加载指令9 i  x! _3 u* [; D) F' q! H+ I1 o, r  Y+ j
0 R8 L/ z9 D+ G& q9 E% R, h
        adr 小范围的地址加载指令/ l* Y7 ?8 G$ L9 _+ W

8 H$ p1 y2 l; M+ I) |        adrl 中等范围的地址加载指令* L4 ]# n  v: F- _" @
: R  a* K" T& h2 v0 o
        nop 空操作
; h: u( K% ^# t2 V# P# U$ X* H, C2 e/ C6 o1 X  F$ K& p& t, W# G
    9、adr和ldr
0 P, f: G. I% n+ Z' g- \. k" `- C3 j. ^
        adr编译时会被1条sub或者add指令替代,而ldr编译时会被一条mov指令替代或者文字池处理。
0 ]/ ?2 q  L! a  X5 @4 ?; ]6 S, ~3 l- S0 i& L
        adr总是以pc为基准来表示地址,因此指令本身和运行地址有关,可以用来检测当前运行地址在
5 i8 S& J  M% y1 [7 ^5 d* H4 @, P2 T7 v
        哪里。6 H  J( t8 o5 ]* E
2 f1 l, s' p" v3 m: d6 C
        ldr加载的地址和链接时给定的地址有关,由链接脚本决定。
* f8 f- G& q9 {; }* H: H: K3 _) }
- |2 \0 w) D7 u    欢迎各位指出不足之处
6 O  w+ ^$ |9 n* {! v& \7 Y5 Q: \, s  D
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-24 11:01 , Processed in 0.187500 second(s), 27 queries , Gzip On.

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

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

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