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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
编器将文字池放在每节的末尾。 这些节的末尾是由下一节开始处的 AREA 指令定义的,或者是由汇编代码末尾的 END 指令定义的。位于所包含的文件末尾的 END 指令并不表示一节的结束
5 \9 n% X( ?8 p0 t* N7 s+ U+ f( b. j: d$ ?0 \0 X6 t4 E3 p7 m
ADR伪指令实例/ n/ h$ h; q, O* j1 B
1 r1 m/ ~( \2 ?; ~1 P, ~6 p
;设置本段程序的名称及属性
4 u( Z1 Z4 K6 t  _& X# E& \
# u6 i( p7 K3 W; hAREA   adrlabel ,CODE,READONLY
& ?- J0 S2 l, ~+ a- y. c$ [  ?. I7 n# q" L# D
             ENTRY
2 F" T- ]6 Q) {" I2 _& l9 C
3 J% k1 @9 |" \3 vstart
3 _1 s) W  Y  o2 h. X, r9 g+ v8 g; e$ j
;跳转到子程序func执行' h* }" m* R- ]4 {  b

9 M$ g! m5 C5 I  B- S             BL  func
2 u2 {1 R9 L" A* Z( B
$ R: O9 v$ ^) c5 K- q4 N1 r0 _;调用angel_SWIreason_ReportException
6 L0 p2 c+ t, @9 |& [' H* `; S6 u9 @! I4 K1 k! }
;ADP_Stopped_ApplicationExit
. \5 N/ L  o" w# L& s: l
/ R, f; [/ [% [4 X;ARM semihosting SWI
: N8 H0 r5 n8 n' W5 q, C. t7 V1 ^/ S( @! a/ `
stop! T& X0 M& h! p, p) r
3 F2 ?7 n! r  Y% O8 ], h+ w/ s
            MOV  R0,#0X18                  ;将0X18赋值给R0,0x18立即数对应宏angel_SWIreason_ReportException(为SWI调用准备参数)
7 h9 O# R1 l! v" B8 l' v- h4 S2 c0 L) `/ k. x
             LDR   R1,=0X20026           ;将0X20026 赋值给R1,0X20026 立即数对应宏ADP_Stopped_ApplicationExit,表示程序正常退出(准备调用SWI的ADP_Stopped_ApplicationExit)          SWI   0X123456                 ;结束程序,将控制权交给调试器(semihosting软中断调用)$ d. r4 Z0 c- C  \. Q7 D

' j1 X$ |6 X9 B& v应用程序终止:在执行主代码后,应用程序会将控制权返回给调试器,以此来终止执行,此操作是通过将ARM半主机SVC(缺省为0X123456)与下列参数结合使用来完成的,R0=0x18.r1=0x20026
2 B  P8 h( e7 g" B/ C
  w. j- y4 X' _% ~, H) j;定义一个数据缓冲区,用于生成地址标号相对于PC的偏移量
: s* ~: q( b9 b! C. d% m5 x# H1 P) h1 u' K1 D
            LTORG! z' R; x7 m1 Y! T
/ t  x" ~& G- l) d7 m
func
* \9 H0 t$ Q' {/ ?+ U& l6 n. @) Z1 [, U4 o7 d+ w/ p) F/ e' R* o
;下面的伪指令ADR被汇编成:SUB  R0,PC ,#OFFSET TO START/ P  ~" h' o. H4 ?  b8 E3 {8 C3 F
# T+ g- w, b+ {) I8 P0 t! ?
            ADR  R0,start
) z' D$ V2 X+ M7 n6 p; @( b# U4 w4 J
;下面的伪指令ADR被汇编成:ADD  R1,PC,#OFFSET TO DataArea' k, T. c6 d7 [5 f# z

7 C' T6 d3 e+ ]4 E* Z            ADR  R1,DataArea
7 o# o3 C- O& G" t! y& I, V: ]5 v2 U0 M8 z* d
;下面的伪指令ADR汇编时错误,因为第二个操作数不能用DataArea+4300表示
! J! O! h4 A2 B- ?6 Y- G$ g4 I
, k2 w- I+ A/ x. d5 B) O6 d' f ;         ADR  R2,DataArea+4300(超出范围了)
5 C$ `2 G: V) `; L# J, Z1 i0 \0 s. Y) u
;下面的伪指令ADRL被汇编成两条指令:
( E2 ^& I* Y  s! ?
  P8 W; `. Q/ z- [3 C& P;          ADD  R2 ,PC,#OFFSET1
5 S4 x4 A2 j, h1 F5 ~6 Z9 U7 T& c2 s4 f% G" G, y- u
;            ADD  R2,R2,#OFFSET20 s# \1 L) X: o( d2 v, P

' H7 K2 S: g( \) f' I             ADRL   R3 ,DataArea+4300: s) a4 _& R: E6 }- ?
* S0 q  m( Z: W/ H$ U
;从子程序func返回
, B" l& a* x) ?! T9 s) G: e
) F9 A+ C0 \1 F! z- B0 S( w2 t7 B             MOV  PC,LR
1 p& R3 o# J( z$ Y! g! A
1 E5 c4 ]. f$ g. i& W- X;从当前位置起保存8000字节存储单元! C7 Y1 O  @; U1 O0 E+ P; X

, \! R/ v, L6 @;并将其初始化为00 L) p2 }9 A: J" X9 \0 b

" X" b, b% v, p2 p5 f" A# GDataArea     SPACE    8000
+ ^2 D( }: k5 L3 u, y( q9 O! ~/ W2 G. E: {+ X
;结束汇编0 Q, P$ s8 s+ h* Q; G! a. f
3 |+ g: P9 W' N  m$ a
             END0 r# `4 d; B0 W
8 y! a& V* y9 D% C1 E
利用跳转表实现程序跳转实例- ?4 K0 g& l2 S3 K1 h  v

1 {; _7 D1 @9 m  h- L& Q;设置本段程序的名称和属性
) p1 i8 J5 q% j) z& B% w% B! B% ~$ p- H$ M, \2 y* J8 S
AREA  JUMP  ,CODE,READONLY
4 \5 t! U; h- }) G5 d0 d, d" E/ f( ?+ V( j) r
;跳转表中的子程序个数$ ]) J9 E5 ~- u* o2 x0 ~
; b, G( L: d  V. {% _* q; M
num   EQU   2
/ G7 X( ~( h% p
6 N$ ~6 x  }7 d/ f! z;程序执行的入口点
/ T4 l6 b% v5 d8 _4 }7 A, D" m
- ?" W! W4 D* `2 P- ]6 \          ENTRY# K, h. k& q1 q0 y7 e! o

; Z+ O& E: ?. t6 jstart! ^' C4 S4 @+ G6 _3 F

. T" N$ O# Q' m;设置3个参数,然后调用子程序arithfunc,进行算术运算
* J7 f* G- b/ o$ c$ ]: d
) T7 r# r1 ^* H7 U& y9 J# p1 q3 Q% ^          MOV  R0,#0' b* @$ i. w- n& P! K" L6 ?
8 M. X0 `: b' N3 R9 V/ P* v
          MOV  R1,#3
4 n' ^8 s# _7 A. ?0 h7 C4 k  l& ^; w& h: N
          MOV  R2 ,#29 C$ o* d" [  n1 }8 f

. o0 y8 D; u" v% e3 x* k;调用子程序arithfunc
; R+ [0 m( ~1 N0 l
' g) b& U1 L+ |# j          BL  arithfunc
  u; z2 F7 u2 P- ]( M: a' I
9 ~8 A2 e7 V5 }stop$ v) q" |$ a% b8 C/ b+ u( a8 A, y

5 r2 W3 ]3 r& x;调用angel_SWIreason_ReportException  V3 ]2 D) ?" \' i& H. R+ j

. j/ `, b2 t5 ^* R$ \  A;ADP_Stopped_ApplicationExit& F' @' c3 s- G4 |

6 H% J' \( Q+ j* b) }! o;ARM semihosting SWI
; F# h9 f6 _7 w4 H+ a" U$ n/ Y3 Z6 f6 n; H- w/ f
;从应用程序中退出( Q, Z0 ?( Z) V' Y* `# b  a1 l/ j
3 c, q/ M; j0 g# l* N9 K& F
          MOV  R0,#0X18( r/ A# f4 g6 [2 g0 N, `
. k  q0 ^& }: _  Z8 C
          LDR   R1,=0X20026
5 k5 t/ o3 {* b3 `5 ~
) h. `5 [7 O& R" G: K  T& C          SWI  0X123456
, I3 B5 J. ]6 e1 _, _" l; }3 J+ E/ I4 p6 S) l- Q1 v
;子程序arithfunc入口点3 f% E9 h% U, r" U9 y" [7 \# m1 |* K

  z5 }( R$ a0 z# Q7 tarithfunc
& P1 E4 [( X# h2 C+ U3 n% \1 f* _  {8 A
;判断选择子程序的参数是否在有效范围内' m/ y* ~, I0 Q1 u7 b
' n8 f" }- x7 `# w0 g! e
          CMP  R0,#num/ s8 n4 ^3 `% _0 h" G& h

/ u- g6 J9 D! D$ b( g5 K+ K! Z2 D) e          MOVHS  PC, LR
5 V0 X* _# ^; s  {4 F3 F1 [" m; H# v  I4 X3 F. v8 \
;读取跳转表的基地址1 ~  I9 E+ r4 ?! _
8 S" i, N3 n8 r& @9 a. G
          ADR  R3,JUMPTABLE6 C7 j" h, S# ~
* X9 G# |1 t& q& A# l: l( I
;根据参数R0的值跳转到相应的子程序3 U0 ~" I0 E  O! C! v4 w, [' \
9 A/ C5 m$ Q/ P, p  L# |4 x4 G5 m
          LDR  PC,[R3,R0,LSL#2]
" L1 K3 _& S0 Z
. C1 X8 E. @' Q! y; }; u! Y;跳转表JUMPTABLE中保存了各个子程序的地址
: K6 I4 h& l! m7 R( E2 ?" S; d7 @9 h: I/ D0 A+ Q: R
;在这里有两个子程序DoAdd和DoSub
7 N7 M5 I/ x2 p9 g9 M% v- j- B8 g7 \" s$ E# V9 b, D. Y
;当参数R0为0时选择DoAdd
- p- S' e6 }% f4 C' l& K3 I
1 z8 a( r* T& c% K- a9 Q4 g' x) A;当参数R0为1时选择DoSub, ]4 _5 p) _; N* |3 V1 ?; _

% }/ |, Y  |6 w1 wJUMPTABLE
; m* p! Q! K7 @6 K
$ `* V" l5 h. [                DCD  DoAdd) _/ p7 T0 R7 M) r( g5 M

6 h/ J# D9 P2 J; d# z# @; e                DCD  DoSub  c# x0 G2 u+ z, S# w4 I. M

1 D1 T( S- P0 D( U;子程序DoAdd执行加法操作
& t: b/ i2 w* D* l' |1 A  j* @7 R! b2 H* Y
DoAdd3 x7 D; R9 x9 C/ g/ ]: E3 d
3 D* }: g0 t) q& F
            ADD  R0 ,R1,R2
6 I9 s+ F4 ]' o* l( _, n' K- C% `% i* J* u' Y0 {
            MOV  PC,LR5 b" a1 V+ G% ~1 f+ W# v3 c

+ L; ~7 Q5 S8 n7 B( l5 v& u- X;子程序DoSub执行减法操作. {/ }0 g$ V' A8 g- R) {

1 ~+ Y3 b+ v5 p5 @( c3 WDoSub
' u9 f+ F+ L$ K2 v
- b9 v/ M. O5 u! t            SUB  R0,R1,R2
7 a4 l. g" ]/ s: b2 f( X& H! I6 h; C" ^' Z
            MOV PC,LR3 n, K9 c, [3 A# `
) u2 X$ H4 @4 y7 B9 D
;结束汇编) s- w. r% P- J. b" t: ~& ^8 L

: v5 T( g4 m3 Z. _5 T5 t            END1 F% j5 {9 B% X  H, Z4 ?  S# p

$ V+ m  a$ J/ s- ~! \, s; i
! }8 X# V( M% @& Z: x( I
3 ?7 [; W- w/ O6 i% F$ |: e% F
+ s3 [- s! s! U( R7 \2 P- b4 T1 x( \1 p* a
伪指令LDR的用法实例
* X- ]1 c7 s# B8 R
3 p- Y# i  j; p4 \/ q7 y;设置本段程序的名称及属性1 J7 B/ u# p; i, W. {& s; ?

( k' y: Z, _) w, F3 H/ E9 ?7 TAREA    LDRlabel  ,CODE,READONLY
. m: A6 I' u3 v/ |) z2 X& ^: ?6 C) P9 v
;程序执行的入口点
1 `' [, M( H7 E4 G" ?7 ]
5 ~7 @  h) A: ?; q  J. q            ENTRY
& Y- c0 u8 e  ]2 V5 T( _  G+ S  V* K
start
3 N$ q" \0 w2 C2 ?# t" G6 x
2 l0 R8 I6 j1 I$ i; Z0 @;跳转到子程序func1及func2执行
; D; g7 E' T% S1 M. P! J+ S/ i3 {" X$ \0 B% i: |
            BL   func1
) M9 U. q; A6 l  V* H) U. [$ j. d! K/ O+ E
            BL   func2
2 N9 e, v8 T0 C9 ]
* j6 C, N' ^3 \& j' D) P0 Y;调用宏angel_SWIreason_ReportException+ P4 @7 |/ |; _$ h

5 \! q2 l; N8 `" i! p* Y9 v;ADP_Stopped_ApplicationExit
. f2 c0 f* _. s" Y4 j0 x/ K' s$ J; a, Z1 y
;ARM semihosting SWI8 z& K5 n1 w- I) C
# E0 F, u/ ^/ R, J8 q/ P7 H  q
;从应用程序中退出: s2 Z6 l! z9 {  U/ k" t' f  e

- l$ c' ~/ z7 A& V( G            MOV   R0,#0X18
* E/ B; e/ ~8 M  i, r* n3 b. x' I6 Q1 X$ {
            LDR    R1,=0X200261 F$ _- {3 g8 W5 r" f
1 C' @8 B# @3 c) o( `; P! i
            SWI   0X123456- l" {% p8 X# e

( t; a0 q: j! A+ U7 V1 o# f$ D$ \func1/ s# _0 T: F0 ~! J
% B  q  s, D6 a5 I% e" q
;下面伪指令被汇编成: LDR  R0,[PC,#OFFSET TO LITPOOL1]
  d# M1 _* ?" u1 V$ ^3 i0 r, k* e5 X# @! [
            LDR  R0,=start7 `& O$ g0 G2 d/ R3 r

5 V3 }& ~% t9 R  W- |9 @2 u/ i# {% G;下面伪指令被汇编成:LDR R1,[PC,#OFFSET TO LITPOOL1]
  @6 J; U: u2 h0 z$ b- v7 \
9 d8 D; ^' S8 f* X" Y+ W            LDR  R1,=Darea+124 @+ ?) Z! x1 M! u. q- b" C% u0 Y2 C

$ [1 p$ N- Q( t;下面伪指令被汇编成:LDR R2,[PC,#OFFSET TO LITPOOL1]: e" c+ ?  }+ A/ J
  q$ e+ E3 ?# ]( h- Q, g
            LDR  R2,=Darea+6000
* W9 j, M2 G+ Y0 G
. f/ S& B: G, c+ c;程序返回" ^* A+ R. J+ `+ T) N

9 m& j$ h! w- S3 `+ k" g+ m/ t+ S            MOV  PC ,LR
) ?# ~( n* |3 @& p! j& m
$ F! @9 J! |: N' Z3 F;字符缓冲区literal pool 1
. M+ V6 L) ]* A( D1 k! Q/ p6 P  }  p  e+ F& z( I
            LTORG
- N' a; j- }3 i5 Y# @! {, e% u5 E9 d2 z0 N! v
func2
7 N, R, k) }8 ]5 k' }
" H: R! q; g$ \) m2 ^+ t;下面的伪指令被汇编成:LDR  R3,[PC,#OFFSET TO LITPOOL 1]$ S, H8 J- j+ |% X

* Y+ `. I( Y+ ]& B' E2 \5 U ;共有前面的字符缓冲区
" ^2 ~9 C6 y% ^! q& G7 D$ Z  [% R8 }& r
            LDR  R3,=Darea+60007 V4 H# g2 i+ j- f7 V0 s

, B' q+ g: {: R+ W  H;下面的伪指令如果不注释掉,汇编时会出错7 w4 X3 r4 v8 q

0 l- [) e: s7 n  x" \;因为字符缓冲区litpool 2 超出了被伪指令可以到达的范围
- P' n" g0 E7 ]- ~  U! H
, }  A# @! w. `1 ~% u. ?             ;LDR R4,=Darea+6004
5 c/ `: v6 ]4 y$ q
& m( T  |/ t! Q8 h  h* f% B;程序返回
* O! A( m5 s9 y2 K0 h
! j. }9 h5 U: t; c+ ~            MOV  PC ,LR
8 [3 R2 j& b+ H9 r" T
  ?2 w- l9 x9 J4 ?+ a+ B9 d+ J8 [;从当前地址开始,保留8000字节的存储单元
: G, [3 D; S4 W% R2 f
6 w) Q+ @: i6 c! k4 J* a;并将其内容初始化为0
* o! @9 x' s7 M$ i; r* ?" p1 u) s0 x7 o, T# X( y! D
Darea    SPACE  8000
' H% h7 B9 l' W4 Y; n
. T9 Z* Q9 z1 m;字符缓冲区litpool2 应该从这里开始
9 \/ N% W- O2 G) v! z  f8 K; S+ M. d" ]3 c$ m
;它超出了前面被注释掉的伪指令所能够到达的范围
4 _0 \, K3 b' @' R* q( H* `4 `! \5 L% W2 F5 v- J+ {$ b1 B7 L
             END

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-24 20:47 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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