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

ARM程序结构&Image文件结构

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

3 f' W5 t0 S7 n% [- ~& ^% w1 g4 U说明:
. G. Y1 W8 l! ?4 Q- T" U3 C1、今天学习到ARM程序,于是到网上找了不少资料,发现真正有用的并不是很多。而且经过我的实际测试,与网上部分大神说的有不少出入。
& ~$ P) ]- h4 U6 L6 I' Z! G
/ E% d3 r, ^2 W2、测试环境 WinXp  RVDS2.2的编译器和连接器) N2 ~7 V* v5 o8 y! W/ N6 t9 |
- ~5 |& P) J2 d, U( Y
3、关于测试使用的工具           ! I3 x% n8 r1 B2 W
6 t" s8 S! ^2 f+ b: Q, X- J8 U6 ]
一、ARM程序的组成
+ I$ q4 G  V; N- q* {4 i2 Q! [: i, V2 I8 Z# ^4 [2 W/ ~: R
此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的映像(image)文件。烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。) H, O1 c" q5 k
9 Z0 H) u3 e4 [2 k. V0 z7 G
一个ARM程序包含3部分:RO,RW 和 ZI
1 Y  r6 a7 E1 l4 q* I, N$ B- r
RO:是程序中的指令和常量      ,ReadOnly    只读的代码段和常量$ W- N: i: c# E! @( h8 C
RW:是程序中的已初始化变量  , ReadWrite  可读写的全局变量和静态变量
8 \+ d& {9 n; Z+ P; \* m9 c+ cZI:是程序中的未初始化的变量 , ZeroInit      RW段中要被初始化为零的变量的段(也就是说该段包含在RW内)& p4 L) U9 n; s- w* [: j2 t/ k2 F
由以上3点在C语言中的表现:
* y/ I4 ^2 D: S: Y% X$ A" {, _1 W: s" i+ V5 O
1、C 中的指令以及常量被编译后是RO类型数据。
5 z$ g8 _, o3 ]3 x! l: L8 p* X2、C 中的未被初始化或初始化为0的变量编译后是ZI类型数据。(这点注意)
( v+ J! ?( S! g3、C 中的已被初始化成非0值的变量编译后是RW类型数据。( l# S  _1 t$ @1 R# H* ?* N

5 I( d& S3 z! J( B关于上面的这些,我将在下面,用实际的例子来说明。0 {+ c+ h' U. B5 P6 V# r

0 f* u7 S" x$ G- @二、ARM映像文件的组成7 f3 O7 ~8 \) l$ P) ?& Q

  t+ I# o- z) b. l        所谓ARM映像文件其实就是可执行文件,也成为image文件,又叫ELF文件。包括bin或hex两种格式,可以直接烧到rom里执行。在AXD调试过程中,我们调试的是 .axf 文件,其实这也是一种映像文件,它只是在bin文件中加了一个文件头和一些调试信息。; N7 k) |$ W& R* I# t" }

" ], t  ^4 ?1 ^        映像文件一般由域组成,域最多由三个输出段组成(RO,RW,ZI)组成,输出段又由输入段组成。所谓域,指的就是整个bin映像文件所处在的区域,它又分为加载域和运行域。我们输入的代码,一般有代码部分和数据部分,这就是所谓的输入段,经过编译后就变成了bin文件中RO段和RW段,还有所谓的ZI段,这就是输出段。
  I' V8 h0 I* r4 A. m" F' t; T; y8 J4 L0 U
       加载域:就是Image被静态存放的区域,一般就是指烧在flash中的整个bin文件;
2 k/ k' g7 f  Z- L% B0 Q, w" u. t; @
: N1 p! i; m: N6 |. H: L& O7 m       运行域:通常是程序都是被搬到SDRAM中运行,该Image被搬在SDRAM里工作所处的地址空间就是运行域。
) }% C2 J) k  @! R8 `) Z7 z
' o% h3 h* B4 E) H* V7 o$ h对于加载域中的输出段,一般来说RO段后面紧跟着RW段,RW段后面紧跟着ZI段。在运行域中这些输出段并不连续,但RW和ZI一定是连着的。ZI段和RW段中的数据其实可以是RW属性。
4 f2 }  U  ~1 i+ H+ Y4 O. v# Z0 K3 r. O1 Y. Z. z. L% m  A
        Image文件一般只包含了RO和RW数据。之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。- z  M) ?! D; j6 j, K8 p/ G8 q
  y9 y  g. o+ t  }
实际上,ROM中的指令至少应该有这样的功能:$ P0 C! m( M% |( V9 o: [
        1、将RW从ROM中搬到RAM中。因为RW是变量,变量不能存在ROM中。! R8 [" u( K: x' K: s* [
        2、将ZI所在的RAM区域全部清零。因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中
' O: W8 X/ n+ k' k6 x在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。' I8 z9 m6 |. f7 j: o2 c2 h; z

/ I0 A6 n4 N  n三、实例测试* ~5 ?) p9 }: w

6 r) x: x1 m1 r( R+ w0 u(1) RO段测试* D/ `$ r3 w) P/ P/ V

: b8 m" ~& p6 J5 b) M5 Z下面两段程序,他们之间差了一条语句,这条语句就是声明一个字符常量。因此按照我们之前说的,他们之间应该只会在RO数据中一条语句的大小。
) X! e- ~# v) _, [7 H2 v, d0 ?/ o
Pro1:9 q$ G7 N$ P4 g7 p- o! Q

# L* c2 R. ^' Z3 w( f+ [5 q7 c3 o   1: #include , F" E2 m: d+ J, b% ]

! z7 R/ t' U- j. ]0 g9 ~( K   2: void main(void)
- Y" l8 E0 `) s1 ?- X
7 k" E8 P& W/ d4 I  ~0 u   3: {
! r! D, E, i1 m+ m3 d6 |8 D( b7 @7 C7 f9 {) l5 B6 g8 V
   4: ;
+ J- ~9 E4 w, s% z" [8 e  h$ X3 j/ ?/ M: Y" M7 s/ g2 r! Z
   5: }0 |. r1 X1 c6 J7 b
Pro2:
# B+ S% y7 G" \+ W4 G
! M8 X9 K; S4 C) M
7 ~5 m- V4 F& }3 A0 O8 Y   1: #include
; o6 d) e( A( G/ Y2 ?0 v
, D9 b3 z& D4 T- P" m   2: const char ch = 2;  // 常量2 |+ D# |7 W7 W$ {0 n2 J

$ X+ ^6 l3 N8 }1 Y   3: void main(void)$ p! B2 _$ _% T" Q& V: ~" ?
. |& f8 J; c& W6 m2 W
   4: {7 Q3 v9 t9 {4 X0 A3 z) A3 q
4 w6 q- R% ^& m2 _) M7 `) l
   5: ;
* v- a; U9 y# E
; W' g0 a$ V. P* x* Z$ p   6: }* ?" V% i- f8 b# j- P
Pro3:
0 v6 L+ K# r  m/ W1 F% w. g1 R" q5 ?( V9 ]. H4 u! D
% F& b3 z' R8 ?" v; x
   1: #include ! G& Q1 b: Z, o1 P, n% Y8 |' T) {

& s/ U! A8 S, C* z$ q   2: const char ch = 2;
! t7 d2 u) x+ F; f7 I4 ^& f' X; Q/ h& t  y' t+ o
   3: int main(void)& [0 e$ V8 T5 N$ G, r

/ d$ i" ?$ \; l+ a   4: {% Z& k" a/ a- O: k$ V

- W5 i+ C' S5 }   5:     return 0;8 T9 n' w, E- `/ N

2 q* k% T% c% ?1 ?   6: }8 p4 ^1 i5 ~: N3 Z2 L8 L& k* Y
Pro1的编译结果:/ t9 O# C% B1 c! e/ U

7 `* ~- I/ v4 b# q& w! A. f# r1 ]* \      Code   (inc. data)   RO Data    RW Data    ZI Data      Debug  
" m7 ?* P4 M4 h$ R2 h( _" e4 T. d9 _0 w& Z8 V, v, L; u
      932      32           16          0         96          0   Grand Totals
7 X7 I0 t% a7 i6 t/ @      932      32           16          0         96          0   Image Totals, Q& j- n/ f' c
" f0 U+ R. S' B
================================================================================
( {% d) C3 }4 Q" X3 ?. K6 K* V5 f' x5 C
    Total RO  Size (Code + RO Data)                          948 (   0.93kB)4 T7 x" u& J9 J( l5 U# W
    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB)% M9 h; ~% x! G- q8 t: L7 K
    Total ROM Size (Code + RO Data + RW Data)        948 (   0.93kB)
3 c: Q" d) R$ h6 Y% C5 q& k- {8 A4 b2 M5 S( H! j3 F% q4 K; Z
================================================================================9 J6 q1 Q& \# N

: x1 H: h4 M" T3 s. K8 |+ B8 YPro2的编译结果:
- d, m) Q, L5 B: S9 l, u$ Q
' e1 V1 U5 y; k% Y" f" C      Code  (inc. data)   RO Data    RW Data    ZI Data      Debug  6 w! g" a  U+ f+ U% a

3 P+ q9 j# d& Z, \" X. r      932      32         20          0         96          0   Grand Totals* [. m, H9 x9 F0 _
      932      32         20          0         96          0   Image Totals. X& W' R- J8 m" r( D1 x
& d3 O$ P; m5 o- L- K% G8 Z- n
================================================================================8 y, @1 W0 D* e4 _; V9 ]
# c# q7 ]' _5 m2 @
    Total RO  Size (Code + RO Data)                          952 (   0.93kB)
8 W: f1 }4 v1 `/ N    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB)6 A! }# @1 z; @7 _
    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB), t/ }6 d( Q) Y% {6 u$ t

& p1 Y4 v! ~9 l5 F. a7 V! [================================================================================  O% z5 F, f$ I. J' N* _
9 Z) _& t  J% M3 y. H
Pro3的编译结果:% G; r. a! X0 e+ y

$ k) x6 Z6 `! B% P3 {) }6 G      Code    (inc. data)   RO Data    RW Data    ZI Data      Debug  
3 {, ]/ i' [, p* }" N5 x- _2 W
8 ]/ z* C; r' P4 A      936         32             20              0             96          0   Grand Totals/ H; }( \* {/ B: I
      936         32             20              0             96          0   Image Totals
" `# f7 o' E/ _' T( z& D
7 W; q; h; H2 x0 t+ u8 F5 Y================================================================================8 D0 ~  q( f7 N; s. n8 m
! |. D5 E- ]9 q3 d# S; |, G
    Total RO  Size (Code + RO Data)                          956 (   0.93kB)3 ]5 ]/ g" }  E  a
    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB). y$ I/ M4 l- G
    Total ROM Size (Code + RO Data + RW Data)        956 (   0.93kB)
6 Z' ]+ r: y' ]6 H
8 I; o4 }' Z7 V. U3 G================================================================================% l: I6 y  I& l+ V
, R' d& Q  `8 B8 q" f
由上面的编译结果(尤其是加红部分)可知:常量被放在了 RO段中,验证第一点。增加一条语句时,Code部分大小增大。+ v3 t0 h  g  l* j
- e3 @0 S7 ]' I" ]( k
(2) RW段测试
2 f) \* z# Z$ t* _
) H  M2 {  r( W/ U0 \. p) lPro4和Pro1 之间只相差一个“已初始化为非零的变量“,按照之前所讲的,已初始化的变量应该是算在RW中的,所以两个程序之间应该是RW大小有区别。3 l. u  q& v) u& L) Z' X- S1 D
" Z6 Q$ }; y; t
Pro4:) L$ b2 m$ [8 L4 U7 J7 P6 i: P
) I0 I0 H- F% F" S6 E/ R

  C. U$ z) |# Y8 W2 v! Z* v. \   1: #include
  v5 q0 f- P8 J  ]( h) \
/ d; g0 e. Q8 [" R; x! ~9 y   2: char a = 5;5 {1 n. j+ C* X, N! t

/ W3 O, D$ V& l  [% k( [   3: void main(void); S9 R6 [/ H% {, o
$ I; i4 H, |  n
   4: {
' |2 t. d7 {; U3 u6 a. T
$ ^: N. ]- m/ c. D/ @% m   5: ;
( g( t2 q* m2 y5 b
% I* V) ^! I8 c   6: }
% _; R% e1 O9 ]+ J7 KPro5:
/ e4 ^9 [' H& ]8 j2 o
: Q& \2 f3 _; s4 Q0 A$ Y4 W% e1 U
   1: #include ! O( H# q* |2 ^" X1 ?3 J$ {

7 I& a3 w3 v2 Y4 l, q   2: char a = 0;# u8 t4 W9 m* ^+ k3 Z( q; ?$ t
7 U8 z# l( o) g4 F. b
   3: void main(void)
; Z8 }; f. L$ H8 {2 j) f# W/ d6 O/ n0 B& W9 e
   4: {
! ^# a5 w* _9 h: N6 J
. T* J* G, _: v, c, a   5: ;8 `: w0 r; |3 z5 ^

, C/ m) q; W( z7 n: r   6: }
0 v, `" i4 `. W  k, x" QPro4 的编译结果:
* ~; ?% h0 u- n. Q7 K; n+ a* N$ I2 H: C- H; S
      Code     (inc. data)   RO Data    RW Data    ZI Data      Debug  + B' k0 J2 V/ l) F1 C; W4 l# P2 V: w0 L

' ?; u' N; ~8 Q6 d3 L3 e       932         32              16            4             96          0   Grand Totals
' a) V7 O( S; C5 Q  T/ r1 M$ \8 w       932         32              16            4             96          0   Image Totals/ i3 K# c9 ~; H; X
; a' L) k) k' m( I  q3 N
================================================================================
' }% G8 {3 Z& J9 q
% @$ X( ~) J  A2 I    Total RO  Size (Code + RO Data)                          948 (   0.93kB)
/ G4 |2 J/ Z3 W4 f! s3 t* n9 M* {    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB)4 u. P, r- \% b% n1 R
    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)
6 G- i; d2 F* w0 g; ^
& c+ ^! L; I8 E0 X================================================================================
4 G. X" |. Z4 }! }5 A+ Q
% m$ {2 C# l) cPro5 的编译结果:
  M2 r5 v7 d2 j  R
" u  M7 |7 q! m. c$ U  S      Code     (inc. data)   RO Data    RW Data    ZI Data      Debug  
, H, Z" F* r- d* i* o/ D
* U1 n( V: H" c       932         32             16              4             96          0   Grand Totals
% W1 M' y, @& x, c' W2 a+ R       932         32             16              4             96          0   Image Totals- ?9 |6 I6 w7 X4 E! N

( s6 [# P5 E. T( d- D================================================================================
; b2 A( k1 V2 W: I  m
0 z, S, @/ s4 w( q    Total RO  Size (Code + RO Data)                          948 (   0.93kB)
" c, K: p; a1 O- @) r! E    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB)
% q* S( N  P8 N3 V    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)- }/ p0 C* T: m; b$ @1 G4 ]
8 e, ~( Q' c$ R9 `% I6 t
================================================================================* g& t% ~8 E# L! A; c
/ g& G8 v2 u6 ^: Y% q
Pro4与 Pro1 相比,只有 RW Data段 多了4字节。
6 S8 x* Q: [$ h" c2 r0 J# a6 a( b; J/ J( g* {
在Pro5中,对于初始化为0的变量,其仍然放在了RW区。
  p9 v( x0 P( c: T/ s! m+ n3 a' @9 |, i' o2 w* i$ B7 A
(3) ZI 段测试9 A8 p5 T9 r" x( i  m$ E

9 z- D5 r# Q+ Y; P1 @% ?* ^; `/ UPro5 和 Pro1 之间的差别是一个未初始化的变量“a”,从之前的了解中,应该可以推测,这两个程序之间应该只有ZI大小有差别。/ _8 F& t: F. U; D2 m
1 G: [+ P- \, t& D6 H
Pro5:) Z/ v9 Z9 b. z2 ]6 k( [0 [

& u* {3 s" T+ ?9 S" Q1 \4 C" S& {- g$ V, r
   1: #include
; f5 @  L: K2 V
" f) k1 y3 c+ X2 G/ q   2: char a;
: u; x1 P7 p3 b$ Q, Z
0 Z3 R: }) W( U) W8 e* R6 {6 o( h   3: void main(void)/ W% o1 Z* Z! U5 N+ {' Q

0 f3 b: y6 f0 w$ C. Q   4: {5 y0 p2 U5 z& h2 b: x6 ?% L

5 L/ [, q8 A. O5 B   5: ;
$ b- P$ E  m* H: T
4 y" S% @% {3 f- Y' w1 b4 F; f2 Q   6: }- x. R6 z/ ~: `' X/ ^3 X
Pro5的编译结果:
! a1 m! T9 p3 w, H1 r. J; k# ~1 Z- `4 g9 e  V, F5 a
      Code      (inc. data)   RO Data    RW Data    ZI Data      Debug  
) p# B( [4 P% u) e% k0 j3 R, V) K1 s+ L& C2 g4 K
       932             32          16             4             96          0   Grand Totals, p: }5 R+ O2 P+ g  c" Y
       932             32          16             4             96          0   Image Totals# E* g" R" r6 r  m! h, d% [
7 M$ U$ `! v9 x; c  b
================================================================================
" x, x! z! j3 @6 C: J$ w$ T) S1 z. c" T, }+ o7 V7 R" v* c8 g5 u
    Total RO  Size (Code + RO Data)                          948 (   0.93kB)
4 ^! Z; Y1 q' l/ s# \) _. i- v    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB)
8 Q" Q- w; N; s9 [) M6 @: X    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)1 s2 u$ W, T% E7 B, b% N: b6 R; n
+ X& F7 `3 R/ j/ Y, t, f$ N( [/ w3 Y- J
================================================================================
7 M2 S, `# z# y  O2 I  \3 D( ^
$ e. z; P7 Z( I' H! [实际情况是,未初始化的变量放在了 RW区,而不是ZI区。3 X" o: ~; p. T; A! _: e

: p* i8 c( @" _( x四、总结
/ P+ M; b) C: n通过上面的测试发现,ZI根本就没用到。这很费解。以下是Pro5的完整编译文件
* [$ i2 ^7 W1 F* [. J! E1 P( Z# v3 b
ARM Linker, RVCT2.2 [Build 349]/ c$ h7 `, n) q- ~
2 N# G! b8 v; C/ p
================================================================================! N/ F  D1 G: `) n6 s& F  }; ]

4 y( }; y8 m  g( u* ^4 `Memory Map of the image6 |( K- X! w1 K% X0 n
+ u1 q: s1 D$ a' Q+ }5 ]
  Image Entry point : 0x00008000
% P. m6 w2 a/ x/ [5 n% g  r3 p2 R' b/ I# K5 e" S: U
  Load Region LR_1 (Base: 0x00008000, Size: 0x000003b8, Max: 0xffffffff, ABSOLUTE)
0 u" M" `! w4 l$ k, k. j2 B3 p2 U+ J5 N
    Execution Region ER_RO (Base: 0x00008000, Size: 0x000003b4, Max: 0xffffffff, ABSOLUTE)
, V0 d4 w" m+ ?; D$ q8 U  v5 H9 ~& i
    Base Addr    Size         Type   Attr      Idx    E Section Name        Object
: h; c0 x: v3 \* W# t) w, f8 i% j3 a& t$ Z6 q2 d2 \$ b7 R6 i
    0x00008000   0x00000008   Code   RO            6  * !!!main             __main.o(c_a__un.l)
4 P" t, g1 W1 ]; E8 J9 l2 c4 [    0x00008008   0x00000038   Code   RO           26    !!!scatter          __scatter.o(c_a__un.l)2 W  |$ Q* J# g
    0x00008040   0x0000002c   Code   RO           27    !!handler_zi        __scatter_zi.o(c_a__un.l); ]/ [5 f2 N, D4 e( J7 D! O
    0x0000806c   0x00000010   Code   RO           11    .emb_text           lib_init.o(c_a__un.l)
* t) i1 H/ g; f6 q    0x0000807c   0x00000004   Code   RO            1    .text               test.o1 q! T1 h7 w, y! i8 ~0 d
    0x00008080   0x00000048   Code   RO            7    .text               kernel.o(c_a__un.l)) \1 M4 O* [+ i6 ?
    0x000080c8   0x00000018   Code   RO            8    .text               sys_exit.o(c_a__un.l)
$ X* L$ A2 K9 U  B0 A9 E$ o    0x000080e0   0x00000018   Code   RO , w/ f& Z9 q0 ]( N0 Y! \
6 j) q2 Q: i: B9 q" y

/ W0 v) `, s3 u8 r: N
+ t3 p' _1 ]$ \6 g: S8 d6 @; U3 }. s: C4 [

该用户从未签到

2#
发表于 2020-7-2 16:20 | 只看该作者
“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的映像(image)文件
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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