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

ARM体系结构与编程学习(6)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-12-1 15:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

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

x
编器将文字池放在每节的末尾。 这些节的末尾是由下一节开始处的 AREA 指令定义的,或者是由汇编代码末尾的 END 指令定义的。位于所包含的文件末尾的 END 指令并不表示一节的结束
- K4 Q; N' k# u+ U" C7 h9 @. T5 }+ c/ Z
ADR伪指令实例
! L1 c# M/ g/ g
1 v! i" h9 a9 }/ F  g7 M;设置本段程序的名称及属性
5 A2 v3 R0 {* `' }* ^4 G
8 O( U% y7 t: [* `/ x9 Y1 D5 Z' [% ZAREA   adrlabel ,CODE,READONLY# Q$ L& |$ [8 I: y% _
! ?- k; L& o# f# ~
             ENTRY  }' X# _, H1 X7 }& K9 V

- W, s& D' J$ f$ o. S6 e, Lstart- ?; u) Z8 L: o& y% v, U
  K* M' C  y0 s3 j  i) J* `$ E
;跳转到子程序func执行9 X1 n* z! O1 v. t

' E' o1 E& c( N9 o1 c5 u             BL  func- K) U8 h' }5 y

# ?+ u0 {. Q7 `8 h9 K3 d6 d;调用angel_SWIreason_ReportException
" E8 _6 K/ U0 \3 t1 D
+ _) @- T/ \1 f  J% s5 \;ADP_Stopped_ApplicationExit
& Z1 F* y" C* Z: e) l$ a' |! k, Q: [4 w, ~, U
;ARM semihosting SWI" D" D# `% U2 T6 i: v& |

) I+ L# X9 K8 ]& b9 K/ Q% e% ]stop
  ?1 U0 M7 d; q/ }' p9 v" M  s7 w, n" O8 l
            MOV  R0,#0X18                  ;将0X18赋值给R0,0x18立即数对应宏angel_SWIreason_ReportException(为SWI调用准备参数)0 t: m& n. v/ j  x1 o/ @% z* u: i7 M: y
) c. e8 S) B% i! b- N0 G
             LDR   R1,=0X20026           ;将0X20026 赋值给R1,0X20026 立即数对应宏ADP_Stopped_ApplicationExit,表示程序正常退出(准备调用SWI的ADP_Stopped_ApplicationExit)          SWI   0X123456                 ;结束程序,将控制权交给调试器(semihosting软中断调用)
4 x' x+ ?: m5 a
( `9 o0 Y% ?) F1 ?/ x! y- X应用程序终止:在执行主代码后,应用程序会将控制权返回给调试器,以此来终止执行,此操作是通过将ARM半主机SVC(缺省为0X123456)与下列参数结合使用来完成的,R0=0x18.r1=0x20026/ `3 s/ N5 C: B) Q% \, o
: b! `6 t2 P8 Z+ k
;定义一个数据缓冲区,用于生成地址标号相对于PC的偏移量
( n; d* h, B3 h4 D6 g. H9 M
$ P, T1 L3 h. E5 v! g            LTORG
$ q- C6 i% j8 f5 x/ U( s6 @/ @
% s; I7 i$ C. f2 t( j- @func* `5 y8 r: D$ l0 o
; J( \' H6 N# Y0 O
;下面的伪指令ADR被汇编成:SUB  R0,PC ,#OFFSET TO START5 }. F, o6 y/ A9 |& R
! ~8 l4 F+ {( Q  D7 M
            ADR  R0,start
  s3 f( h$ V# m: T1 E( O7 o* t; V' k. A! L; D* k" W4 `; q
;下面的伪指令ADR被汇编成:ADD  R1,PC,#OFFSET TO DataArea
% ]$ ?5 o. K4 b. Y. ]3 H1 \( A4 b
: ~9 U& p, G( U: A3 ?            ADR  R1,DataArea# F* l1 G5 x/ ]) g1 H* x" a; ]/ A

# [% D! \  {/ U' g;下面的伪指令ADR汇编时错误,因为第二个操作数不能用DataArea+4300表示
4 n4 I- R1 t2 L. `& \6 Z0 a' O* l- W: W& Q. m/ C5 d  o$ h2 \
;         ADR  R2,DataArea+4300(超出范围了): p0 P2 j, g. h5 u2 k

; \8 S% C$ i. A0 `/ d;下面的伪指令ADRL被汇编成两条指令:* [% K" j  w0 k& h* Q

& s! M% ~" G7 T# h( B+ t;          ADD  R2 ,PC,#OFFSET1
4 S  |1 {6 Q. F: L; ~
, h8 t0 C0 g) ^; d- X;            ADD  R2,R2,#OFFSET2. a/ s* s$ X# E$ e* J

* C, E3 X; P# R; u6 U             ADRL   R3 ,DataArea+43005 d) a) L8 g3 `0 }

$ f0 z8 [8 ?/ `* Y4 [5 w;从子程序func返回
$ V+ E2 _2 `7 q, C
4 T/ J1 P, U6 _# D             MOV  PC,LR. a. r' c$ g8 X+ `9 g

0 R' X- g5 x# O, i) X; e; X& Z;从当前位置起保存8000字节存储单元
; |5 a; d4 G0 I  D7 w# t5 j- j6 h& |) ~
;并将其初始化为01 d( p- r8 ~' m6 y

# o8 V/ L" I, V3 x% v9 yDataArea     SPACE    8000
1 ?# n  C3 I; m- K$ D  `7 l7 e  m
9 y# e, s  U) J6 q, M/ w3 a;结束汇编9 g  I( C% y( E

5 Y$ G  ~! v* Q9 m2 ~9 _  K             END
" i  f* e! g& U5 d6 b7 d5 j; g2 }" g3 p+ o! Z. a; r' S. G
利用跳转表实现程序跳转实例
3 i% z- W' G: F. b3 V- O
5 W/ Q+ D- h: M7 V5 Z7 \! N;设置本段程序的名称和属性
( i3 Q: O; I+ ~& Y0 W" }9 n- R/ @1 _- k
AREA  JUMP  ,CODE,READONLY
; n2 \2 r4 L* _, q2 o9 o; N8 H) w: b+ P$ l
;跳转表中的子程序个数
- _# b0 }# O# r9 a! _( a, Z
& K& G7 C! t  C- u# D( o+ \num   EQU   25 s8 o% y) }( j

% I$ k% k7 D( T$ Z! [;程序执行的入口点
- W: g$ l" o+ t" l# h8 N3 r/ |$ ?5 a0 Q1 [' W: k
          ENTRY
2 A, g% h1 ~1 e! G
- [& ~9 s  o. J+ S) Cstart9 g" Z0 z! f5 N2 O- J8 G
# i3 B  L% ~. W+ m' g; O/ o9 g% K
;设置3个参数,然后调用子程序arithfunc,进行算术运算
& D! Y7 w5 L: h2 x5 x0 W; F$ C3 x
          MOV  R0,#0
, y1 F2 ]% L" R: r8 L& l5 _1 `# k  {
' V9 r. V* K6 g' s          MOV  R1,#3* U, g7 A1 l1 O- m+ k6 v, w7 O4 B

% ~: s, r  i6 n' b; y+ k3 h/ C6 ~2 F$ l          MOV  R2 ,#2# W: V' e/ A. ?" k$ l, C

+ Y$ N9 r& K0 t4 V  N;调用子程序arithfunc
& H% f/ C8 e  v0 q3 f/ a
1 L! E2 U6 l3 F4 e! B, W: e. N0 A          BL  arithfunc4 @* k. P1 M3 h$ @# Z
& U0 V; @, H7 |' W
stop, O5 O6 z3 p, x* Z4 h. k, {/ v
5 P3 R2 t0 j- E1 R+ P* `: a6 ^
;调用angel_SWIreason_ReportException
: O* R5 u/ X3 W! m- M) |1 X& I9 ?" {1 D8 {
;ADP_Stopped_ApplicationExit
! i2 b/ x% |; O2 Z3 L& M, A$ a. O; @3 a. U) ^
;ARM semihosting SWI
5 f- r0 Q+ V# q% k- d- Z6 D4 m
+ A* q) S! E' _9 K0 G;从应用程序中退出& D3 l) O% K& A

7 b" |; x0 C5 M; `" |          MOV  R0,#0X18
0 f; r, f% M, y% }; T8 @" P9 ?
1 S2 u4 O# k: z7 n( \. u          LDR   R1,=0X20026
* m9 T  f  [( j( ^/ S9 Y
  ^. |1 d% x" d, |          SWI  0X123456
+ X) Y( x: L+ U5 d8 }; N* a/ ?6 ^  D9 q* k% L+ S! l7 t
;子程序arithfunc入口点3 M# H6 u) U; {$ f6 ^4 p  b

  x9 X9 P0 f, V8 [& karithfunc1 `( {6 t; ?( h# B$ F
4 e. l. S/ M9 U! F% S; Z, y
;判断选择子程序的参数是否在有效范围内
: y0 f6 s4 k- q: f! R
3 u" u5 a- g4 ?: }5 v          CMP  R0,#num( W( {; p' b/ b1 e
7 j% S# I0 m4 c2 K( Q
          MOVHS  PC, LR4 J6 K0 g' T4 ]( C
: A% W' V! Q! r! R/ U( S  e- D
;读取跳转表的基地址* C! H5 X9 Q# g, J* S; K3 l
! ]& O. _3 y, y& N
          ADR  R3,JUMPTABLE
3 P) |8 n6 g4 |# a& ^0 i6 ?) e( G* ~6 P
;根据参数R0的值跳转到相应的子程序1 x& Q! y/ h$ f4 m( \3 D8 g
2 L) K3 f$ ~+ _
          LDR  PC,[R3,R0,LSL#2]
% K7 c9 y  ]: L+ U7 v+ Q
, v$ {; O# {( y- S2 {/ N. n, h;跳转表JUMPTABLE中保存了各个子程序的地址
  p5 `! b5 v, m' u) Y1 }3 y5 T
3 ^6 o0 P# Q& N# m: J; Q6 J. h3 `. K;在这里有两个子程序DoAdd和DoSub! a4 e% E) N2 [' N( B' I' k

1 N: E3 Y; q% E3 k) f2 ~$ t;当参数R0为0时选择DoAdd
3 \/ Y1 L8 b8 v( u) |* e. r1 `, k4 ~9 R2 o& j6 `7 M
;当参数R0为1时选择DoSub
1 J# O# T( T; p0 g( P4 R  e) M7 i! O8 o$ H
JUMPTABLE/ @- n  x) [# i$ a/ ~9 o

/ \. u. f/ A( \& L                DCD  DoAdd0 p4 O% \+ Q! w0 e: [5 k
  T' ?% }& r) v, A( L: }
                DCD  DoSub) Y7 W- f, L9 T7 k( h

5 }7 T$ ]: |- \! l8 I;子程序DoAdd执行加法操作3 g5 ?* O2 R6 t( h
: {) ^" f0 @+ @" H
DoAdd
) e2 Q/ P7 r1 W5 K1 J; U& i" T- ~0 ^# p6 ]6 `
            ADD  R0 ,R1,R2
8 ~- {* I' b6 Q8 H; A& c+ L+ |7 z% d1 g6 }  H9 f- l
            MOV  PC,LR
2 f' Z! W: I0 [1 Z  p6 s$ M/ l# v+ t3 u
" G# _8 ~9 T/ A' H;子程序DoSub执行减法操作/ L" t5 b! }) A6 p$ F
2 w8 X" I( `# R$ U2 O
DoSub1 Y2 G$ m5 g1 e5 I& q8 C

6 l" @2 Q6 ]. G/ i            SUB  R0,R1,R2* A8 e7 _9 G7 I& c( l5 S
* d5 Y) ^% K" @
            MOV PC,LR
+ J7 Q: ]7 P9 D4 Z. N7 `" p( d
' c3 i8 t0 _3 C;结束汇编; u. w; ?% G3 L# u7 U
: @2 s) V- j- S4 a. c; ]+ s
            END
( p; `# a4 E* O2 Z9 Z% u) U) ~! `$ e0 \( i5 }9 L, @
) R/ p/ u: r% @+ C( I

: s$ u. a8 `& o$ [! E; \ " _8 T: q% B# c: F! |* P) \

* J* J8 v0 a# R: s0 W) ]  V- |伪指令LDR的用法实例
3 C7 w0 L' N0 z& [/ f8 j0 m9 @# _( t0 |; |- N3 s
;设置本段程序的名称及属性
1 q2 l1 K: U/ t8 B$ [4 S# r0 [9 w- y) b9 N! L, V, ~4 H- I
AREA    LDRlabel  ,CODE,READONLY) Q$ r# {. u% F; ?
. F" Z$ Z% B* d9 ~; ~3 [( _! B% H
;程序执行的入口点) H1 `" R  R2 K
) R1 P! g  v% w" C. Q+ n+ f
            ENTRY
. R2 i) n/ j1 E, }- |
- \  A. J  t# q/ J! I$ ustart3 H9 \- `6 I& M: H: C# D8 g
5 R* R% ]- w1 H: k& [' ~6 B
;跳转到子程序func1及func2执行$ c/ L4 |4 H' n2 S' {( E2 ?

2 p% t$ ?  z7 e4 }* E' B1 R            BL   func1  M6 t9 O1 W$ }  h# U

: Y; B) `  Z/ I) G% @: D            BL   func2; {6 C! G- p9 A% p. `. T* ^
  K0 N# k$ u1 C  O/ U( L
;调用宏angel_SWIreason_ReportException
* ?+ {8 d) ?& H! ^4 L: D/ K1 I( J3 `( i6 Y$ n1 ]) P& L) z* }
;ADP_Stopped_ApplicationExit
2 U4 x0 U; \5 t7 ]* F6 [' \1 C& R; R& ~% l9 E5 r- s6 N
;ARM semihosting SWI
1 c2 T: d7 x+ [$ Y( i7 i
7 [8 e  w) ?6 m# g5 r& o  x, y;从应用程序中退出. j1 K0 i7 o3 _' ]

: G7 e3 v0 f/ w/ p9 y7 I            MOV   R0,#0X18
3 e  O$ A' a  ]5 F! I
" w8 U4 n. ^& e& ]7 F            LDR    R1,=0X20026  i) v: E0 a" p

2 B$ E, R( s0 K* t            SWI   0X123456
1 r+ P1 G# U6 X9 V7 @
! Y2 K1 Q8 q/ _7 ^! d1 a; [+ vfunc12 ~) C. `2 p1 U
2 J7 w6 F  T, Y% Z8 O: x
;下面伪指令被汇编成: LDR  R0,[PC,#OFFSET TO LITPOOL1]
6 i* D/ F! H7 x2 M" _4 C' v' A
' t" L& g! w1 z9 R6 [8 o9 ?, ], S            LDR  R0,=start
$ ]( P6 n2 w$ e! Z- `. p" l- [7 ^1 k+ k2 K) Q9 W2 a
;下面伪指令被汇编成:LDR R1,[PC,#OFFSET TO LITPOOL1]
! ^8 S$ s- p' {, B" R! P2 |* O3 E1 I; _, o. B- ?5 ]
            LDR  R1,=Darea+12
/ ?  [% L! [. N, ^+ g( O! S; u
: Y' r& U. o- M;下面伪指令被汇编成:LDR R2,[PC,#OFFSET TO LITPOOL1]
: s* d0 v0 z( a+ r& L, S! G- K0 |# D9 \% ?
            LDR  R2,=Darea+6000% l* W+ f' f# @4 ]! p

5 h4 t3 S. ~( ]* k; G0 H  {1 S4 R$ j;程序返回
4 h# x0 {3 I! A. B1 v5 s* D1 ]; y3 r( i
            MOV  PC ,LR9 }3 g  F% l- t2 U
1 \! \4 n4 |% h- t" F$ Y' B( y" {* ]
;字符缓冲区literal pool 17 P. }8 ~- `. M4 ^0 T7 T  W
- ~, T" I" V4 L+ j
            LTORG& A: C  X9 O" `6 T1 R

+ W4 W/ I% E1 X/ z' sfunc2
* N4 h& v: n- y5 E1 h; C% t# o  `* C# t" C, b. ~( n! a( Y
;下面的伪指令被汇编成:LDR  R3,[PC,#OFFSET TO LITPOOL 1]
' _* o0 p% a  _' u
/ |6 s6 M: T. A/ A- C ;共有前面的字符缓冲区
( [& J# }' _  e" n2 _" {9 {/ |7 o; G# O& \
            LDR  R3,=Darea+6000
+ h! n- }" }: ?1 p2 p3 g1 }+ F8 b$ V; A* H: x( @3 ^2 O' `
;下面的伪指令如果不注释掉,汇编时会出错
" I- @2 B! z3 j$ R: S* O
5 R, w1 c. s8 |0 K;因为字符缓冲区litpool 2 超出了被伪指令可以到达的范围
. O0 E8 n/ @) w/ ^0 t+ `$ O# j2 m1 G& T$ A! C9 u$ C6 W8 J. i* u
             ;LDR R4,=Darea+6004& r- a  m, O9 R% s

1 x( ~  M7 y8 d4 A; Q7 p! `;程序返回+ F+ v7 R. d+ @

  t% Z) \" Q: i6 W# q3 w" m& x% m, R            MOV  PC ,LR4 Q6 Q) D; [' U! K) z0 {6 K
! l0 }4 D1 G1 ?7 K2 c
;从当前地址开始,保留8000字节的存储单元/ O* v: v, v4 X" \. j" u

+ T- y& V5 Y3 I7 B, P/ |1 @' B;并将其内容初始化为0
$ |% `$ |" L9 {/ R( b8 ]; Y. b3 Z1 x) G* a2 W. z; Y
Darea    SPACE  8000  M- c' R; t: b% J7 A5 v+ A
5 v6 s* t. D7 B, U2 R+ n3 R* D5 [
;字符缓冲区litpool2 应该从这里开始
5 k+ c3 Q7 S  D) f: S" W* f
/ `1 S3 T$ M0 ~0 n, _- p;它超出了前面被注释掉的伪指令所能够到达的范围
- h5 S7 M  N1 [9 I% N1 _. F+ H3 Y# d1 v, T5 V
             END

该用户从未签到

2#
发表于 2020-12-1 16:26 | 只看该作者
ARM体系结构与编程学习(6)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-25 01:17 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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