EDA365电子论坛网

标题: ARM体系结构与编程学习(6) [打印本页]

作者: piday123    时间: 2020-12-1 15:43
标题: ARM体系结构与编程学习(6)
编器将文字池放在每节的末尾。 这些节的末尾是由下一节开始处的 AREA 指令定义的,或者是由汇编代码末尾的 END 指令定义的。位于所包含的文件末尾的 END 指令并不表示一节的结束
8 A9 V1 J9 z- [9 i' V9 h. z" w, y
  C- ~  Q- Q3 U4 X5 e* mADR伪指令实例; U2 A! V8 H- @, _
  l) t2 [/ k5 V: c
;设置本段程序的名称及属性. m# _8 V+ z0 W! g  M8 ~6 e/ b) O

7 F( }+ A( `" B# T2 `AREA   adrlabel ,CODE,READONLY
' X+ c1 z9 N3 K; J5 ~0 V( L
) B2 F, Q6 k' }4 K' u             ENTRY1 x5 i4 p" x. a9 j; G$ B
+ ]$ H% ?3 w" N/ b$ \# Q1 V7 b* v
start" t1 P* i8 G) r# e! ?

, P; R# Z" {: X. B; z, E! }6 E;跳转到子程序func执行
$ o& u( d( s! }; j: t) ?" D- f$ `# m: m6 j# Y
             BL  func
; x1 E* A) U: h: z. f& |, X6 E
& ^7 h: z! H3 D5 V5 `7 B. F;调用angel_SWIreason_ReportException9 x* e7 M# Z: ?) w" q+ i. v& K
4 W+ ~- D7 x! y/ e: e
;ADP_Stopped_ApplicationExit
8 d, q6 T3 {" R& f; F' U& \+ b- h
;ARM semihosting SWI% l$ P! A' P/ U( M; ^

5 f' R" s- w$ L* ]stop
5 \. v/ A3 H7 Q# C( ]$ f- l# Y. O  D
            MOV  R0,#0X18                  ;将0X18赋值给R0,0x18立即数对应宏angel_SWIreason_ReportException(为SWI调用准备参数)4 u# @9 t( L7 n

; Q+ Y0 S8 k9 _, C6 S             LDR   R1,=0X20026           ;将0X20026 赋值给R1,0X20026 立即数对应宏ADP_Stopped_ApplicationExit,表示程序正常退出(准备调用SWI的ADP_Stopped_ApplicationExit)          SWI   0X123456                 ;结束程序,将控制权交给调试器(semihosting软中断调用)4 v/ y! r+ r6 s6 c  f4 y
/ E4 x( p$ ~8 W' _$ {: o& E# J
应用程序终止:在执行主代码后,应用程序会将控制权返回给调试器,以此来终止执行,此操作是通过将ARM半主机SVC(缺省为0X123456)与下列参数结合使用来完成的,R0=0x18.r1=0x20026  y7 ]( e! X& O/ Z( q

4 [! z/ [5 ]( A7 {# U( V9 A;定义一个数据缓冲区,用于生成地址标号相对于PC的偏移量% y3 w  @) m; i% s; \. s
/ @3 W3 U" l% E, j! y
            LTORG
6 y( G! n7 a4 A3 G6 B0 X! C) X4 @, l2 i% }2 p' O/ U/ h! Z
func
: `7 w, T* ]& ^/ }) {
& w  t. W! |$ z8 I- k;下面的伪指令ADR被汇编成:SUB  R0,PC ,#OFFSET TO START
, R3 C! S  c8 Y) w2 y! X0 o# j6 w
* @. ~; S- p( t* i+ a$ |, @; \            ADR  R0,start
2 J* Q/ J+ Z4 |' z* E
. L* G) [$ s" n" h2 g1 C  v;下面的伪指令ADR被汇编成:ADD  R1,PC,#OFFSET TO DataArea
3 }; N! C! y8 c8 |% n
. u, S5 C+ X: I            ADR  R1,DataArea
) j9 N8 J6 Q: Z1 n( F
. W! G" s5 j5 k" Z( K& o;下面的伪指令ADR汇编时错误,因为第二个操作数不能用DataArea+4300表示6 \4 B7 t" b- I$ o- J

% P. |" z8 C2 j ;         ADR  R2,DataArea+4300(超出范围了)1 y# q% k7 k6 i3 f- [9 s6 d, ^8 L
% m* w+ a0 G) ]& B" ~
;下面的伪指令ADRL被汇编成两条指令:1 k: u0 z+ [/ |2 M. k7 M
: X; O) p" {: H: y! }# s! M2 ~
;          ADD  R2 ,PC,#OFFSET1
$ N3 e& |: G( N5 U
0 Y1 x9 R) }* Y9 E& r( m6 E% m;            ADD  R2,R2,#OFFSET2
: \8 l! I% Q1 F- @% F1 V8 ^/ X, a% _4 l* L
             ADRL   R3 ,DataArea+4300
, X8 Y' C6 ~" G( F) h3 ]
1 |/ A  {1 R# E) I- ^' W;从子程序func返回
" ^6 w: p4 n0 s* R# T0 e# g
* x5 j4 R& D( r  O             MOV  PC,LR
+ O  k& Z; b8 K
# \8 {/ A- R' ~3 `( J5 A;从当前位置起保存8000字节存储单元) @. j+ c( A) l

/ l+ e! @# g" _7 Q;并将其初始化为09 V8 s  y+ y4 P+ I

; n# Q2 U2 L% E1 A+ j' }DataArea     SPACE    8000
6 h, W8 U7 A2 V! D0 Q  }/ U7 {  X, {4 M
;结束汇编  F2 j: m5 T" {* }9 ^+ {$ K2 ~

; {9 A" |( c. j0 L# ]             END' A' D: k$ S- w6 P
1 [% Z' u  I7 B+ g7 [/ e
利用跳转表实现程序跳转实例2 z: t! I1 H9 L' ]8 |, ^/ D
  A& X- F& t' Q# x2 }3 P/ ]; f
;设置本段程序的名称和属性/ ]! m; }: Y; v) M  n: O" [

% Q" A' N7 q, F! j/ e* b) ?AREA  JUMP  ,CODE,READONLY. v# z; e6 J% ^" t8 d! C
; H% z5 e) @5 ~6 u. B* B% ]
;跳转表中的子程序个数( ?7 I8 ~( n6 `/ J
6 A  ^% k$ \: O! g# F9 a: q: R6 S; Y
num   EQU   2
8 N5 ]9 c- `: C" b* f) M0 j; [
. {: M: ?: `/ }) j2 {;程序执行的入口点4 a9 k4 W! R/ b. s' ?
! D" k2 n( G( g' p; {' f
          ENTRY
. j# E6 F' d0 G+ h- |8 O8 }7 O" H- e( ^; @: r
start
( k7 O( z, f) e6 H# D7 M
: N6 e$ }7 ]/ C7 t;设置3个参数,然后调用子程序arithfunc,进行算术运算; Y) Z1 M5 n1 i1 E1 _! ]4 ~
. d5 u+ X: ]  F3 W2 i9 c: x: w0 ?
          MOV  R0,#00 r5 ]' d) w1 ]* Q+ H" d* L* P# N/ @

5 `( c7 {+ t6 p/ D6 I3 l          MOV  R1,#3: W6 ]8 p* ^# b( R; b) j; q) n

2 `" E' g: F6 _3 U! \          MOV  R2 ,#2# Z4 j) ^- m' u3 ]: T  i
% N5 @; w% C" ?% ]; E! p
;调用子程序arithfunc
& g( b' B7 n4 \" J9 B; g2 @- R4 Q# G" m9 f
          BL  arithfunc
* E7 x- ^/ d8 `8 n" q7 c& i& D: q
; J8 b+ ?, E" T7 J4 ystop
+ ~3 d9 o" r  l8 A8 q* }
8 h6 f/ h1 V( o. {;调用angel_SWIreason_ReportException9 a4 J% {* w8 m* K1 L

3 G. H) q0 {/ b+ O;ADP_Stopped_ApplicationExit4 u; m% V9 I0 m$ L4 \, H: ~
! E. Q* {  B$ U& e' o# I4 a
;ARM semihosting SWI& V/ ]3 s% z& E
4 t  G7 i9 I) I5 y% H0 p# Z
;从应用程序中退出
2 f8 y# i( m7 j8 x
, C+ f  o) R$ h! H          MOV  R0,#0X18* b+ g! ^* e' |7 r/ l' u* R2 ?5 e

% }6 Z  F! C' Q3 ]4 n+ R          LDR   R1,=0X20026
9 O+ e: {+ L+ K6 V; m$ S* F; z
1 J4 f; G# @5 I: W# y& w0 d" M          SWI  0X1234565 S  R9 T" K* C7 g9 d+ u8 U

# A3 S1 h) a& |5 x;子程序arithfunc入口点5 J5 @4 y5 T9 F6 F+ P
& U' A3 b! G" _; Y4 [- z7 D5 W
arithfunc: N. J& D% Z* }- ~$ ]5 h8 G$ E( V
. }" Z+ l. ?, A1 L9 C( I
;判断选择子程序的参数是否在有效范围内
! F+ y! A3 N$ W+ ]: w; j* m
5 R, {+ Y" I2 L/ k0 \4 q          CMP  R0,#num
4 @: [" Z+ p  o) V) m" [2 w
3 k0 \: Y2 c' f. K; P; r          MOVHS  PC, LR
+ J5 h0 R; G3 ~* v0 v2 T$ [+ `3 v. @& D8 \7 J  Y% I5 c" L" o7 w9 [
;读取跳转表的基地址, d8 h2 _4 O. y( a

5 |& _3 e3 q# e: [! ~9 d' N          ADR  R3,JUMPTABLE- k# |4 M8 W3 i5 _

6 o! k' [7 r; z" F) s1 G;根据参数R0的值跳转到相应的子程序: a0 u9 ]2 `" x8 K( x  _1 g

. W7 d9 ~- U2 Y          LDR  PC,[R3,R0,LSL#2]
% j% {- a3 L9 S3 F; L% \0 |/ \( E& @& \3 A0 Z# Z# y; E8 V
;跳转表JUMPTABLE中保存了各个子程序的地址
- r  R* h7 p  Z( A3 X" R
- A* a9 Q  ?& v8 V;在这里有两个子程序DoAdd和DoSub; g! E1 }/ U+ z7 ?5 U1 L
. H: t, B% w( k( X
;当参数R0为0时选择DoAdd
, t# `6 t$ }4 n7 k3 P$ J
6 e  D+ l2 S1 C% [, _;当参数R0为1时选择DoSub; c3 w# r6 t8 ^3 H- \5 b* ]1 [
* u; N, q" k- Z! e1 M/ G0 s
JUMPTABLE
' T* S: M" i! `
: M! ~* f" J1 s                DCD  DoAdd
" O* e, w' N, s$ @
1 l* e9 v3 j) w4 v1 M% j$ A                DCD  DoSub
% V9 R0 U( U# x# z$ [$ C/ \# g3 q$ r; L( x
;子程序DoAdd执行加法操作
+ u+ Z8 P+ Q, {2 Y1 \$ G* N0 f, I7 h$ P* f  I6 I5 j8 q
DoAdd
8 c5 W. q. P* {) l5 Y+ k$ c5 [) n7 G1 H! s
            ADD  R0 ,R1,R2- j; |2 n6 f8 z8 y

0 ]8 g+ ~: K9 R. S            MOV  PC,LR# Q) }& v0 O0 o& u5 I, f8 ^& T
; j) I+ w0 T0 b
;子程序DoSub执行减法操作
! E. @" A  k. |8 l
9 i+ Q. H% M- y: j; iDoSub0 z$ P1 `% P0 Q, J* u

& w$ R$ a' ^" L5 A            SUB  R0,R1,R2
3 q: P1 \* [0 K6 j$ R, `! }$ Y% b4 F" h" T. n. E
            MOV PC,LR9 M% ?/ }5 L% G, ]4 \
; R  E. \  n7 ~. |! F4 L
;结束汇编* Q$ O) i/ o6 H3 R& Q

  A1 Q# h) z( E8 P$ l" k' l9 e7 s  E            END! `9 X) o, z3 c. m( W7 A

, ^1 `: y& k& g7 @# ]
8 W+ ^( K5 }+ ?& P/ X5 f" m( h& V+ u/ S" F. Q' ?. D. f' R: _
, M/ V9 d. f* ^% c0 T2 w

2 ^8 P0 l2 l% @; R伪指令LDR的用法实例
: p/ B8 ]" i8 {. I* H" X/ {+ [( \2 J! M) h3 T
;设置本段程序的名称及属性
3 {. P+ r5 |* \' ^9 i! P- j6 M4 c! L3 h- b
AREA    LDRlabel  ,CODE,READONLY% j% N  H& L6 Z( o; R

9 g, m4 J* s/ R( `;程序执行的入口点
+ t2 q* U. v- n3 Q& c) ?& ?* A3 |$ ?0 [; i: U6 O
            ENTRY
; B0 R% c  O7 Z5 Y( [
0 [+ N" Z) V; i1 P, Y- pstart- P" [4 }. b) k  K, s! \9 R
, ~( ^5 k$ T. P) T
;跳转到子程序func1及func2执行
. T: L1 }4 I6 j0 @3 ~1 N& @5 N6 E  p
0 V* p0 ^( \4 _1 j4 B  W            BL   func1
* i5 w! c  f6 f1 A- l/ h
# V; a2 E( \) B3 q: \& J3 ?            BL   func25 U5 X  T$ Q# V* S- r  I, K
& z% m8 r" T  S- n7 p3 x/ b. g1 ~( e
;调用宏angel_SWIreason_ReportException
8 v  F+ ^3 M0 V6 n" Q" q3 s- K; K$ J: @: \) \" A# m7 k) R
;ADP_Stopped_ApplicationExit( \  j3 e3 R, u7 U% ~, t
; O5 _2 G7 ^6 l5 p, k9 p3 \/ a& _
;ARM semihosting SWI
! _+ N% u' ?& J8 z, h0 A2 ]% [* I5 H( y- x7 w- V! R! V
;从应用程序中退出
! [, r9 [$ `2 O' O8 W5 W' M) z4 ^! @3 K2 e
            MOV   R0,#0X18
6 M% d( F; Z8 k$ U
3 `$ I4 j/ E; d* I& k- Z& Y. m- B            LDR    R1,=0X200261 S; M) o4 a% z2 d8 W
& F2 w4 r! _5 S$ ?. N- u
            SWI   0X123456" n- F$ \; j+ D2 b$ g7 K

9 u# w1 b* H+ Tfunc11 |$ b7 G# d) x4 }7 z  n6 v
& J. Y2 m$ e5 q  u. N! c
;下面伪指令被汇编成: LDR  R0,[PC,#OFFSET TO LITPOOL1]
. z2 X3 D) |" m6 ~3 O" g4 L6 D! J% J. Z- m7 j1 E, L. F$ ]% ?
            LDR  R0,=start8 m, J7 V2 A& a8 k# a; A+ u, |( y' r
( w6 f# W% Z) Z5 x9 ^+ i  `  ?
;下面伪指令被汇编成:LDR R1,[PC,#OFFSET TO LITPOOL1]
% @! t7 f# Q7 k/ D/ l' U1 @
( G; m  ?0 @8 R2 l6 s  C  g            LDR  R1,=Darea+121 P, r6 r, `" `+ C$ X8 a6 e- t+ z

& L" X& Q$ ~9 R+ v$ e" K+ b;下面伪指令被汇编成:LDR R2,[PC,#OFFSET TO LITPOOL1]+ B+ W# M' @" O2 Q
; X- Y: V1 `' D- Q! F  m2 a  c& g
            LDR  R2,=Darea+6000% i. K2 F9 f3 O, l% X
# _' _8 W" H8 `# o5 j. \
;程序返回( Z% B7 d# ?, s0 E$ y; n
  b  U. k1 Q5 K$ P
            MOV  PC ,LR
- W$ C0 P) Y; r8 m# n
' x% W, E: F# b+ z8 G% n;字符缓冲区literal pool 1
( ]+ o- k9 S8 O; ?/ u, R3 A/ G8 h, j" B  o
            LTORG
8 j0 J8 A( c( h% }5 Y) s" q9 d7 {1 b  x0 Q/ W  w
func2
* {7 Q+ d! a& A: f2 i: I2 q4 B6 D
  r$ j5 z( K$ ]9 J, d;下面的伪指令被汇编成:LDR  R3,[PC,#OFFSET TO LITPOOL 1]
5 a, h. G$ {9 O) A6 L4 d, A. ?
7 @. R5 Q; |9 L/ Z ;共有前面的字符缓冲区" Z% Y7 Z3 q7 X, E1 j6 t$ P, D

" j! \" n# g3 }% K$ j8 b, y7 z            LDR  R3,=Darea+60001 z9 H% J8 f0 F. ?( J
6 Q( _; i# X$ S& w6 C& l' R: N
;下面的伪指令如果不注释掉,汇编时会出错
4 F6 h. n% u& W! k
2 i5 W2 e& E! d3 G# H' d;因为字符缓冲区litpool 2 超出了被伪指令可以到达的范围9 W5 q8 t: w) e, l7 U2 w3 f8 R/ C

4 _% z* I2 S# I2 v+ Q             ;LDR R4,=Darea+6004
7 G0 {$ \% }$ d3 p( ?' L, W: t  W) D
5 k/ e0 V/ f" s5 M& ^3 k8 p;程序返回- A* g) M7 o$ o* \" E
# A. z3 p. ^6 a: T/ b
            MOV  PC ,LR
% w$ L( P$ S5 \" @* |$ L$ q  {
2 O, E0 |9 S* K% |$ L6 Z6 N;从当前地址开始,保留8000字节的存储单元
& k( z/ k( x2 Z& i
. t3 Z& X( k$ |;并将其内容初始化为0
/ ^& i' _; ~8 \8 F+ W
# ~/ x  }; e! X/ K7 j) HDarea    SPACE  8000
/ N! a0 d$ [: C; F& T& D
" ]1 @8 n! e& V) L7 X;字符缓冲区litpool2 应该从这里开始
; a- W. d. o0 `: U# D, ]$ a
# e: u" B/ y  M. Y: @;它超出了前面被注释掉的伪指令所能够到达的范围
# @! m. H' j! L3 [$ H3 ~' i; h+ {- k1 J/ I0 w+ `' x5 }
             END
作者: CCxiaom    时间: 2020-12-1 16:26
ARM体系结构与编程学习(6)




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2