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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
编器将文字池放在每节的末尾。 这些节的末尾是由下一节开始处的 AREA 指令定义的,或者是由汇编代码末尾的 END 指令定义的。位于所包含的文件末尾的 END 指令并不表示一节的结束
# \5 E/ x+ a- L# d* r3 B% g6 H: I* S0 Z3 y% V5 [! f3 E  i
ADR伪指令实例
6 B/ }# v2 D) H/ X6 X( G, Z4 y( v  A2 K0 ~5 E# F: D$ G+ @+ T; a
;设置本段程序的名称及属性: E1 T+ c& s, \9 U

! q! f, E# J  g7 p) {  s; jAREA   adrlabel ,CODE,READONLY
' U- y  C5 i) Q) w: T' o5 S: I. L: q* a7 n' W( S( |
             ENTRY5 C( ]- F! J+ x0 ~! N  ^0 c7 C4 J2 V

, I$ y/ y) g# H4 s( \8 l" y" t. xstart
- u5 U' K$ C4 L
' z0 w0 G" @, H; K# F) a. [3 f7 P;跳转到子程序func执行  y) h+ W# p/ b8 t" F, V+ H0 a

4 j$ q) x+ u+ a% R+ e             BL  func. x5 T6 ]0 X6 C5 T( L

9 l! i# p4 c3 O8 v8 t% _) E;调用angel_SWIreason_ReportException
- v% \" ^! ~/ ~( Y; q7 u( m' t. g! W5 w& N
;ADP_Stopped_ApplicationExit
3 Y3 J3 s' Z; ~4 B* I
" d8 g0 A# U0 H4 L;ARM semihosting SWI
5 @2 A! h. R$ m- U. O
" u& j2 n. }2 |+ Q' lstop! }9 B! w7 E& }

' h/ G- h* i# J, Q! @# ]            MOV  R0,#0X18                  ;将0X18赋值给R0,0x18立即数对应宏angel_SWIreason_ReportException(为SWI调用准备参数)
2 ~$ }& x+ ]1 {- D
0 Y7 A1 ?$ W, s3 f3 r& t1 d             LDR   R1,=0X20026           ;将0X20026 赋值给R1,0X20026 立即数对应宏ADP_Stopped_ApplicationExit,表示程序正常退出(准备调用SWI的ADP_Stopped_ApplicationExit)          SWI   0X123456                 ;结束程序,将控制权交给调试器(semihosting软中断调用)
# U1 h# ?  @' ?8 `; v1 j# E/ @7 H* E- C/ I2 l
应用程序终止:在执行主代码后,应用程序会将控制权返回给调试器,以此来终止执行,此操作是通过将ARM半主机SVC(缺省为0X123456)与下列参数结合使用来完成的,R0=0x18.r1=0x20026/ _+ a& F0 j$ l

9 L/ V4 d7 v( x) k;定义一个数据缓冲区,用于生成地址标号相对于PC的偏移量: \8 I7 x! g0 q( H0 G

% I$ {6 L& n5 T# D0 p4 n& O5 o            LTORG! E: L& `9 m. a, O/ k

" @5 X; {; {, C: _  ]' ifunc
6 k% f# y  \: ]# `( V9 L
: ]4 ]4 {. X! E( L- F7 M;下面的伪指令ADR被汇编成:SUB  R0,PC ,#OFFSET TO START; g8 n4 V' t# s6 T. q) Z
9 |. j+ b* ^+ D# e" [7 s3 \
            ADR  R0,start; A& ^3 F; _: N0 ]
% E7 m1 X; E4 A) t
;下面的伪指令ADR被汇编成:ADD  R1,PC,#OFFSET TO DataArea% W; ?5 i: k2 w; ?, Z1 T

* [4 ~: b2 \' F' F            ADR  R1,DataArea3 R4 q. O, N$ |! ?$ M$ o0 q

7 I- q8 y* }- R) O# a;下面的伪指令ADR汇编时错误,因为第二个操作数不能用DataArea+4300表示0 F' F+ u4 L7 L$ Y  S: e

; F. @  w4 B" O9 t$ `( z) z; S ;         ADR  R2,DataArea+4300(超出范围了)! }7 \7 V$ i- \( j9 a4 h7 {" K

/ I& T" ?  i6 Z9 R0 r$ x;下面的伪指令ADRL被汇编成两条指令:
' m6 x' L; T2 z3 k8 A. T( Y3 `
) e4 [; P( R% z3 b, R- P# X* r;          ADD  R2 ,PC,#OFFSET1
, W' A" F0 J" |0 I' Y0 T$ h+ l0 f6 U* @: k
;            ADD  R2,R2,#OFFSET2
4 B0 j+ o. ?7 l. A3 u
( M; A  ^9 I1 |" V             ADRL   R3 ,DataArea+4300
& k9 B$ v- o. z( a' I
- r7 B0 g9 l0 k7 W8 D" \;从子程序func返回
- w. t! v& ~, D+ J" p; C$ j5 x
/ F, s1 O& Y, G             MOV  PC,LR
5 J/ X) }# u, T
3 ]( `& X+ n& t8 K;从当前位置起保存8000字节存储单元  F% l( }, R9 o- P: }
3 `5 Z* G% g: u; v# l+ [
;并将其初始化为0
+ t' A' X$ W5 l2 ?& x9 Z" N
7 q, k9 @; L7 A( dDataArea     SPACE    8000
. A# o/ E: E/ L( S# i' `& B
1 V; i# O% A% o0 A5 b6 g;结束汇编) Q; Q* U, L/ A. d
* g( Y( x) x" n  X7 Q
             END
% ?- L7 N: D0 \! w. E1 M- s7 P+ K& W/ i2 \
利用跳转表实现程序跳转实例
! g7 d* G( Q" c2 f# w( P" `( z2 J# E& t* |/ k+ o
;设置本段程序的名称和属性. k4 m* f2 ^+ Q! C/ b
4 r$ y" d  d, k" ?8 G$ }$ D/ t$ s
AREA  JUMP  ,CODE,READONLY" j4 J: `# {4 C' J) e) ^+ b

4 L3 s/ B3 v. {  I' u" y;跳转表中的子程序个数' y/ Y. `5 R4 h% o# @

: [. U2 [  J% I/ ], U' Knum   EQU   2
! _3 J( ?, O3 U# K3 o) ^; o; m. G
* R5 A! F+ v  ~: a1 j% Y9 O;程序执行的入口点9 ]9 X6 f$ i' }
/ q; A3 y( L# B! m
          ENTRY! E$ n* q( x: |5 w; J

1 K5 p1 R7 F% v, V; ~: W! Istart
+ c4 C" G7 U3 G- R/ n7 N' j" Y2 [) _# t3 x
; Y- Y3 M/ a; h6 [;设置3个参数,然后调用子程序arithfunc,进行算术运算: \* m( m1 f6 F; b0 k9 M

9 B* I9 T1 a7 u" e  }          MOV  R0,#0; Y& D0 c3 N% D

: z, l  o% S0 J' u          MOV  R1,#3) W/ y  M7 R0 g( s

7 T; |! p& d3 z! b          MOV  R2 ,#2  ]+ a6 p7 J6 y- P; `& P' @2 C; a

1 Y' h1 ~, o- X8 A; h/ v;调用子程序arithfunc- T3 F) _2 x  q, _. T- G% w

! M* d0 S4 h) ]          BL  arithfunc
$ p% G  Y$ C4 L2 K  s3 Y5 j0 ~+ a8 A
stop
) v' g" Y3 b! x0 H. C5 S* S$ J5 B
;调用angel_SWIreason_ReportException
0 h/ j. M; a) W" E+ q- m9 U/ ?+ E
  o* H: ?7 n! B9 _  V8 F9 y;ADP_Stopped_ApplicationExit5 p* z- C) V& E

: K+ u% O5 J9 z. Y% A;ARM semihosting SWI
( W, r" o4 |8 \7 ^' v/ f
. L* I0 K. H; n3 z3 L: [& e, W, _;从应用程序中退出
; u6 ~. h( H" ^  u3 ~! N! l7 H7 ~( e# I' G  ]
          MOV  R0,#0X18; R3 w( k! r( V; K

) `9 l* E# H+ y) k7 T          LDR   R1,=0X20026
3 e3 Z) j+ Z+ x, q/ f
- H" R; W0 o9 M' F  b) h$ J6 }          SWI  0X123456$ K/ H+ \4 z. w1 u3 g5 o5 `

, z- D0 w1 r0 B;子程序arithfunc入口点
* O7 t2 d5 A  H& g! k6 e7 [/ W' x7 }# e1 d4 `; ~
arithfunc
7 f: z/ G0 T9 k  ]3 {: E& L: G8 O4 q
;判断选择子程序的参数是否在有效范围内) t0 ^( [' w  w, p. S9 a

; a) L. w. `6 P7 y' c$ D          CMP  R0,#num# b# o4 @7 t2 @
$ i  ]8 ^' \" p
          MOVHS  PC, LR
6 |2 W+ T) ]8 v8 f' `, S
* X% E% \4 O- H% e- e2 g$ k;读取跳转表的基地址
( F% Q1 T& \0 j
" {( O4 [) w0 x6 L$ x! C+ c0 Q          ADR  R3,JUMPTABLE, a: W1 S5 u. @, h8 [( v. U( l( B, S

( g6 {; @0 T* c, M/ }% t; k;根据参数R0的值跳转到相应的子程序- C: ~& K; u" {. g% [$ f- s% k
  {6 o4 A( ~. @
          LDR  PC,[R3,R0,LSL#2]  S+ i# w7 V; [: r" D: ~5 t7 `& ~
' o4 q' {' E# Y& a0 J) }
;跳转表JUMPTABLE中保存了各个子程序的地址
! H2 a- ^) }+ _3 a! |# n, Z4 s4 ], B% R3 Q4 Q( K6 g
;在这里有两个子程序DoAdd和DoSub, M  [7 F+ c! @3 m* Y% G1 \

4 e/ M& `0 h5 I/ X2 d1 c;当参数R0为0时选择DoAdd
3 W" o# T' ]  w$ O- T) b' ^6 b6 H3 J
;当参数R0为1时选择DoSub$ J! U! M0 v# G5 y

, g5 P6 n( V( K, C4 [- gJUMPTABLE
' K) ^: R6 z- f6 I- M1 b
/ f5 N+ J. y% a                DCD  DoAdd
: Z; q0 C8 J7 h; m, ?' d8 \; t  I4 o" q, u  B6 a  R
                DCD  DoSub- F" _. @' L5 D) L7 p

* ?- t" O$ x# I! Q/ m;子程序DoAdd执行加法操作- d& W; U- [; Z" g& s

$ g  s- O* f8 H; P, oDoAdd
- H& V2 n# H8 A6 r& _" i9 E! x% v* i7 `0 F' N% D' @$ q
            ADD  R0 ,R1,R2: _* y( e; b- Q3 U+ R
0 U6 _. C! }' u5 r! V
            MOV  PC,LR
$ c" G0 [! d8 J* I* W7 {& I; Z  z
; U# f! u4 m! n; M. G# |;子程序DoSub执行减法操作/ ?8 D& d7 j. p; Q
  d" k; k' ~# g/ n
DoSub; s. b" n9 V: V. U9 x4 v3 N+ h

; g8 D$ j; E% H/ N4 U            SUB  R0,R1,R2% y- q' @' l$ i  c7 g9 Z& X

4 R) D) j9 C+ M  ?" }! ]            MOV PC,LR0 t# c+ }" b! Z7 p* q: B2 }5 Z# S# h# m# J

+ l$ e  _9 y& I% F& d, K9 y9 ^6 i;结束汇编( k8 M7 J6 O. B' f4 c

4 n) p) i% a" l8 y2 o            END3 \5 ]; t8 m( @0 C! Z6 F2 ~

, R+ q2 A8 X0 w) u0 A 1 X( g7 a6 {( W9 S: I

8 S' W- f3 H7 |0 W- m
3 S$ ~4 ?$ x$ {8 T6 j; y0 ?) _7 V
& a# p5 ~* t' [( z伪指令LDR的用法实例
5 @/ @8 p$ A( Q; y3 n8 e" m0 A2 D2 R$ V4 O6 P) h$ V& N+ |" J3 u9 @
;设置本段程序的名称及属性; g* ?4 H  `! X/ ^' j

( k' m2 g$ S/ z3 wAREA    LDRlabel  ,CODE,READONLY
. D' s7 K7 C7 q# i0 q; g2 [
3 `1 J' @; i% e% F1 Z;程序执行的入口点
8 M$ D8 d- j8 f7 q+ ?7 s' ^1 k% B  v# D+ G  j+ b1 O6 ~) i
            ENTRY
. Y( F4 Z9 Y8 N6 T0 e( n' \6 n- q# i9 @8 ~: t1 G- Z# ^
start0 m0 ]4 ^2 @5 n+ L! Q! }' J
! x% j+ a! z; M2 K2 K0 }7 n& X
;跳转到子程序func1及func2执行
5 X0 r* Z( _# Y0 B, v( z  L4 R) E& L" }/ S! H4 [% u! p" v: Z
            BL   func12 y. Y; E# W5 ?1 o4 t5 }
- u8 v8 y# v: U2 j" z8 t
            BL   func2
* Q- k) t) I& v. e# [% l( Q9 W5 L7 e; i* H. h: b% _
;调用宏angel_SWIreason_ReportException
9 D( \8 H6 _* K
/ w% W7 B8 S  h1 m& a;ADP_Stopped_ApplicationExit9 ~# p! y6 ?' K4 [' \" o( F

  M. `+ P1 Y4 Z' L& d' x- e;ARM semihosting SWI
9 L! E1 j) J5 R+ v! n" n8 \: N5 }
0 p; T" [- y  H;从应用程序中退出
( S4 K; J2 s6 i6 A: D+ G4 p  c6 N( d5 T' t( E7 h' p
            MOV   R0,#0X18
& t" Q! R( {9 V. t) K7 }  g2 C: z7 L& H  M6 A2 q* c2 S
            LDR    R1,=0X20026
8 X6 x9 r7 O1 `0 z, B1 q
. N6 q' l6 L/ |            SWI   0X123456  K7 s) |, k: u; K( u8 v# V% \

: {' N& G& E) x- qfunc1
7 Y' M5 Y: `8 o3 ^* P! f% \3 P; q9 u4 c
;下面伪指令被汇编成: LDR  R0,[PC,#OFFSET TO LITPOOL1]. I1 w% v8 m. w% V1 D

2 P; ]* r( O4 c/ h  k            LDR  R0,=start
# e' ~" E" E' H/ `9 l* K$ F/ f2 G! ^7 i5 p* m. x
;下面伪指令被汇编成:LDR R1,[PC,#OFFSET TO LITPOOL1]( _3 G3 p/ l  l' T( S" E: [
  r5 ?% {3 T0 F
            LDR  R1,=Darea+12
- F* z6 n" D3 {( k
3 k  ?) Q& A' m8 ^6 G;下面伪指令被汇编成:LDR R2,[PC,#OFFSET TO LITPOOL1]  U  D0 d7 z# x$ c, C1 c2 ^  X
' T, D+ t6 D3 V5 R
            LDR  R2,=Darea+6000
# x/ M* q1 n0 m, }! H1 `# a% ^# U8 t3 Z: I" C( d) u1 k
;程序返回
* V& s2 O, }! m2 N( a9 V2 {3 G8 o1 e9 k
            MOV  PC ,LR7 }9 ]" W. ~0 e: h1 ]7 s5 ~

8 [& u  U0 t0 g8 P* \# r  z( _9 S;字符缓冲区literal pool 1. k0 O. X2 T3 E
8 h4 j$ {% H! a  W6 G; }
            LTORG
& ~; _- h, K$ g* _
' Y2 D9 t# W; \6 Z- Sfunc2+ W/ a3 B# \0 O/ Z2 @4 X( b
. x& M6 y- o" Y( L' O# Z7 b8 b
;下面的伪指令被汇编成:LDR  R3,[PC,#OFFSET TO LITPOOL 1]
2 ]3 v& q' q6 G" Y. r2 ?2 ~7 t8 _8 m! t$ C) d, A) G
;共有前面的字符缓冲区
. M! h/ O: ]# D# c
8 I6 q! M9 V! r& P. F7 i/ s            LDR  R3,=Darea+6000; v; k2 q5 M. s4 x
2 ^  k& `+ N7 }. b
;下面的伪指令如果不注释掉,汇编时会出错
( O: F/ x4 ~- L9 o/ k; n+ A' V9 O: W% X0 V3 o- Y
;因为字符缓冲区litpool 2 超出了被伪指令可以到达的范围
4 t  O; `4 p  Z/ Q6 O: l3 g
. i. [- o6 w) V* ]. v' U             ;LDR R4,=Darea+6004% ]5 ~; k0 \% h8 i1 i$ d: o

& E: i. w" p) V" G9 ^( s+ Y- c;程序返回8 @, m) @% j! e+ f3 m6 |- b, y

! E+ m8 o2 o7 c8 {+ @+ C( H            MOV  PC ,LR
: v2 Z! H. e. y
- r- d6 j* K3 j/ Q6 I0 @2 T( k;从当前地址开始,保留8000字节的存储单元
6 f- e. c; V# L0 r: {5 r- j1 J0 F# R" V
;并将其内容初始化为0
7 u* E2 Z( G: K- ?- ]2 l5 Z# H7 M
' \/ h5 y# u* \% b5 O6 ]Darea    SPACE  80003 H! j& h) J3 N% v9 r% H# y

/ \  F9 H# l3 i9 P$ B' E; L. e;字符缓冲区litpool2 应该从这里开始6 d/ P- q/ e9 Y" U6 W8 l4 D
  ~. w+ b9 t* E7 O2 [
;它超出了前面被注释掉的伪指令所能够到达的范围
0 B1 N  C& O& s7 d, q  e
0 h2 V# h! X0 y# Q  ]" K$ K             END

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-24 19:41 , Processed in 0.171875 second(s), 23 queries , Gzip On.

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

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

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