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

ARM程序结构&Image文件结构

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
8 d* ?5 ~( W6 W( ~  K. f% d- d# e
说明:* T# L6 g- J* ]( k
1、今天学习到ARM程序,于是到网上找了不少资料,发现真正有用的并不是很多。而且经过我的实际测试,与网上部分大神说的有不少出入。9 \$ y( f& p( n& G. D& P

2 Q+ X- v5 [( u( g2 V. J( R+ @4 m) z2、测试环境 WinXp  RVDS2.2的编译器和连接器2 G6 I; H5 `$ ?

, K/ E8 B5 ~, S! u3 W3 r3、关于测试使用的工具           3 s. P. @# T8 F. S4 P

8 t0 `3 i9 V1 l- E: ~一、ARM程序的组成7 `5 I& T. d% W3 g9 M5 Z2 k

, O' w. Z/ ^, |- g# E此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的映像(image)文件。烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。: T7 l# q. I  o1 Z2 D/ A6 n
8 ?8 |3 Z! S! T
一个ARM程序包含3部分:RO,RW 和 ZI$ u6 q' Z, v; L* W+ U7 h
! j* b! |* K; m5 i3 _7 n
RO:是程序中的指令和常量      ,ReadOnly    只读的代码段和常量
/ N* B+ v: {3 uRW:是程序中的已初始化变量  , ReadWrite  可读写的全局变量和静态变量
8 D, l* I1 b* pZI:是程序中的未初始化的变量 , ZeroInit      RW段中要被初始化为零的变量的段(也就是说该段包含在RW内)
6 X! U7 g- Y/ t由以上3点在C语言中的表现:
, G9 d: u3 d9 u3 r& N0 j6 r: n6 @5 T- ~
1、C 中的指令以及常量被编译后是RO类型数据。
" `% M+ u. i0 b6 n/ m% |2、C 中的未被初始化或初始化为0的变量编译后是ZI类型数据。(这点注意)
/ K/ I5 d/ T+ G% n) K. y3、C 中的已被初始化成非0值的变量编译后是RW类型数据。
; \, `3 A* T6 P- c) D, V( X5 O) W* g8 x! ?) z& \4 d3 R8 g; L
关于上面的这些,我将在下面,用实际的例子来说明。
- W% G6 [  o9 Q  d" ?( a* p
. }5 `5 e# r" H二、ARM映像文件的组成
1 W8 S* a# B+ D( q2 M/ ]
$ U* M/ Q/ m: R  s+ z4 ]- H        所谓ARM映像文件其实就是可执行文件,也成为image文件,又叫ELF文件。包括bin或hex两种格式,可以直接烧到rom里执行。在AXD调试过程中,我们调试的是 .axf 文件,其实这也是一种映像文件,它只是在bin文件中加了一个文件头和一些调试信息。
! w, v9 _) \3 U1 F$ {$ \4 z, D. F7 J: e) C, I3 F) v
        映像文件一般由域组成,域最多由三个输出段组成(RO,RW,ZI)组成,输出段又由输入段组成。所谓域,指的就是整个bin映像文件所处在的区域,它又分为加载域和运行域。我们输入的代码,一般有代码部分和数据部分,这就是所谓的输入段,经过编译后就变成了bin文件中RO段和RW段,还有所谓的ZI段,这就是输出段。
4 X7 P1 O" U2 P( }" y4 n0 I
  T( {+ x9 D& r( W9 n% @1 ]       加载域:就是Image被静态存放的区域,一般就是指烧在flash中的整个bin文件;
9 D1 ]+ r: u2 R
) v$ U9 j+ I. u7 Z7 N       运行域:通常是程序都是被搬到SDRAM中运行,该Image被搬在SDRAM里工作所处的地址空间就是运行域。
$ {7 ?9 k: w4 u) a$ d8 x3 O, _$ u% o4 P0 s4 D6 {* ]) b3 x
对于加载域中的输出段,一般来说RO段后面紧跟着RW段,RW段后面紧跟着ZI段。在运行域中这些输出段并不连续,但RW和ZI一定是连着的。ZI段和RW段中的数据其实可以是RW属性。
8 {/ Z. H1 `3 U+ \
( a  o9 z( y' f% p        Image文件一般只包含了RO和RW数据。之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。
4 M4 P% P) O" G: A
3 {0 n% n( X+ ~( ^& o: t实际上,ROM中的指令至少应该有这样的功能:# R* k4 f! M" \0 s1 y
        1、将RW从ROM中搬到RAM中。因为RW是变量,变量不能存在ROM中。
* j; F* f5 p+ k        2、将ZI所在的RAM区域全部清零。因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中1 w4 s7 w0 w1 d% h; a
在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。9 d  t0 F+ c0 A7 d1 I' H# j/ R( R

! W. t/ o" [2 r, v三、实例测试
8 }& Z& F& q: S* ]- i0 |; ]7 r4 T- s! k
(1) RO段测试* H  Z5 ]! N- s, j
# J! X( o0 f4 V6 ^1 H) {
下面两段程序,他们之间差了一条语句,这条语句就是声明一个字符常量。因此按照我们之前说的,他们之间应该只会在RO数据中一条语句的大小。+ V2 T/ `9 A  ~2 Q

9 D! B" }- [3 O! D& Y2 _: fPro1:
3 e1 J# _/ l; ]/ z, g! [6 e' y" V; I! x. w' ]! |( s) E
   1: #include
! e; Z, e' v  q3 C1 w* r. L+ e
/ m. C- Y2 ]. v: t/ k   2: void main(void)8 H0 g, q1 B( e5 e. A* f
4 [! D$ s# J# S$ N; Q) n) x4 V
   3: {* s) W8 o: ^  N+ u8 U, K
7 c$ |- ^9 a0 s: K& r2 n, s
   4: ;1 O, A. v  ^* C5 k
2 \" ?; i& v. ]# r
   5: }
$ f/ X4 i7 v4 _2 fPro2:3 j9 U, t( u8 h/ I2 e' z0 r  m8 ~
( K% e# k8 }# a

, h( c+ c+ F) e$ Q- E   1: #include * f  i- \0 Q- d, Z0 V

- F# i6 h( [+ T   2: const char ch = 2;  // 常量, }! ]! {: j; j: `) C( j

: n+ ~% s) |4 B   3: void main(void)
( j" \# ^( A5 {% x/ B2 R3 z
4 s9 i, G- d0 p! ?0 r. ^   4: {
: x! d" @0 m: A/ w5 q" K# J8 k3 j  B1 v" c" a4 ~
   5: ;
& I' B; q, u! l+ y* @$ {& d! e* V& q9 f4 d4 z" V
   6: }
% M* P$ H( r( y8 i& k5 zPro3:
3 D  `5 d8 H& b  P' t; J. D& g5 C0 [2 J8 T# Q0 B$ e" u

! S# w4 J- k4 \! Q% p  ?% J! y% g   1: #include
" a% c* {* R8 D; G5 f( Z5 X/ d& B  d5 O( ~; C
   2: const char ch = 2;2 V# Y+ g) @+ ~5 K
# O# R. p* j+ U9 ]
   3: int main(void)
* N1 i/ o, m. u; {4 f: U0 @# L9 h; Z- K( u2 I6 X3 e
   4: {; M8 m# l- T) O: \

5 k* m9 \% ]. ^$ P2 e  i' s1 K   5:     return 0;
+ ?$ Z! }; y/ w. `2 s
% W  ]2 w  [: c0 n! ^  _; G   6: }
: r4 u( W0 v' Q- fPro1的编译结果:
6 |( o: b) R1 I' ?4 u2 y7 ^8 _$ @1 @/ a$ P  Q
      Code   (inc. data)   RO Data    RW Data    ZI Data      Debug  " g; W  X% F: [  k8 M) q2 F# ~
# l  i8 O1 L  n3 |
      932      32           16          0         96          0   Grand Totals4 `; Z  m5 v  h1 u4 N% w# H
      932      32           16          0         96          0   Image Totals
7 F+ M5 W! K0 C: T& w2 p1 J2 J1 a; C* }3 ^
================================================================================
8 L9 f0 F' ^  }* J% t7 i4 m! W6 s0 s: M0 _+ C9 K1 U
    Total RO  Size (Code + RO Data)                          948 (   0.93kB)4 a3 Y9 z- T7 a  [9 l$ z) g5 ~
    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB)$ X4 k. T; L/ g" J! A  k- L( E) Q
    Total ROM Size (Code + RO Data + RW Data)        948 (   0.93kB)
# F; {1 f* Y1 `4 y, h" l' |
0 Q0 {- F7 c* Q7 T1 n9 d2 a) p================================================================================6 {( h% Q: U6 W3 \; Q

" Y9 l7 V- d5 Q1 WPro2的编译结果:: M+ a% H0 L, V0 A: ?3 b2 g" E4 h

, [0 G& z2 d. j+ h4 D      Code  (inc. data)   RO Data    RW Data    ZI Data      Debug  * ]% j! M) Y5 t; e6 q

3 V1 N' {" V3 l* A9 e: h      932      32         20          0         96          0   Grand Totals% \+ Z& q& Q. H" ]% ]0 l
      932      32         20          0         96          0   Image Totals
* C0 D: _) H: a( ]4 e2 w
6 G8 r3 \; K1 K================================================================================/ A5 v0 j& q7 ?5 p5 m7 ]7 S. N( G
; ]3 {- f/ {) C
    Total RO  Size (Code + RO Data)                          952 (   0.93kB)7 z; }3 w- s6 j5 c" w
    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB)
: `* m, g1 h6 G" @& ?  M9 w    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)# a5 r$ Z# U) j/ T9 S  j8 A

+ e9 V  @# A6 I1 N3 E) z$ }================================================================================. o$ a' O. E9 t) S$ j6 M& l& k

- z) F6 I% m, H+ \) C3 B' h7 [# mPro3的编译结果:
: k3 X$ |; b7 p+ ~% Y. ?4 }4 h% c: i6 P0 J
      Code    (inc. data)   RO Data    RW Data    ZI Data      Debug  ) E9 \: r9 A' G- G( `# k6 l
8 y* @: f9 X! A8 E: C+ w0 W5 ?
      936         32             20              0             96          0   Grand Totals
1 T, S" M: `6 j# U7 ?+ n  [" T      936         32             20              0             96          0   Image Totals4 b/ F/ v/ ]; z3 h6 K) l7 E

# l" w0 J. j0 r; ~* R================================================================================- H' U. c7 D4 O9 ]2 k5 h7 Z
4 ^/ V9 z3 V$ z& w1 q; H
    Total RO  Size (Code + RO Data)                          956 (   0.93kB). W8 }3 }' G! E  s, {6 Q! k2 C
    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB)/ Q; ?/ u' p8 B# q* V
    Total ROM Size (Code + RO Data + RW Data)        956 (   0.93kB), u) G: Z6 p( L
) @' J: A# n, `4 A- J
================================================================================2 f) B# u' v; E' Y/ u8 E1 M+ s

  Q- a: I) ]+ j, D: n( u3 P由上面的编译结果(尤其是加红部分)可知:常量被放在了 RO段中,验证第一点。增加一条语句时,Code部分大小增大。- x+ `3 H6 s7 p: F" j$ {2 ]
# `1 @6 ~* R$ v% N. Y9 R
(2) RW段测试* l" Z* S0 y* ?& f4 j) ^

$ ?  d5 n6 g, r+ z* M) b& bPro4和Pro1 之间只相差一个“已初始化为非零的变量“,按照之前所讲的,已初始化的变量应该是算在RW中的,所以两个程序之间应该是RW大小有区别。
8 [! c  Z0 k, ~" h# J6 Y) W- h1 ?7 y6 ]3 M2 X0 }( F( v$ h* T. U
Pro4:  S& P, N9 w! b4 w9 s

) V" |; |0 s- Q; v) B2 `0 w1 e( M7 w, k7 x
   1: #include
5 j" `* z/ y8 A, O6 k/ a; h8 i$ [  p
   2: char a = 5;
$ l# z% J; b; N& D
) n2 P3 q8 l/ o" r: i6 Z   3: void main(void)# e+ X  E5 t- I8 M* w( i

% j& }: B2 t2 L5 O+ r   4: {
( }2 A5 Q. L, W" G& C4 O" T( u6 H- T) c, E& U. w3 a" ]; P
   5: ;
8 ?1 w, L. \3 e5 Y1 Y
# {; c4 y8 |/ ]& ^0 l% _7 _" Q  @8 q   6: }
7 u  |- r* r$ ^  P  `Pro5:
& {! M' P3 @, E) _4 S6 d, D$ C
( U4 D3 B6 T, @9 g7 Z4 k
8 m: Q# \. k1 r+ U% Z   1: #include
& U- b8 ^2 L8 P9 _, m! y: z4 C: c" P  j5 j
   2: char a = 0;
! D- t+ q3 t! L8 U! Q3 K8 u3 v/ F0 C1 @7 U8 J
   3: void main(void)
2 g) D8 c2 R4 `1 R) v
7 D. t' s& b4 y$ O& I   4: {. t* h0 b& k- T7 |

  v0 z7 A( y5 e+ f   5: ;4 n, c: Q8 u" K  Y

0 D5 Q  V+ J9 z   6: }, B* t) S6 g3 X1 h5 F1 p7 E
Pro4 的编译结果:
9 {8 n8 N! z% a6 {
$ a# Z$ g9 w8 P+ y  S      Code     (inc. data)   RO Data    RW Data    ZI Data      Debug  
* E/ E7 X, i! o# c# E. h' g/ C  D5 q
       932         32              16            4             96          0   Grand Totals8 s' ?2 A7 g, L5 t: L) ]
       932         32              16            4             96          0   Image Totals
- |5 U# e  e0 y+ J5 w! H: P- {) g0 B2 v& y
================================================================================4 n/ Y$ O; w: H

9 T" o$ ~) ~% s  Z: ^    Total RO  Size (Code + RO Data)                          948 (   0.93kB)) \: a/ S6 N$ g& G
    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB)6 d5 n# o' {: P- F
    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)* O2 s. @( ?* Q3 n
3 g$ d, c: e! _& y  T; Z4 Q$ M
================================================================================
; Y4 _, q( @* H4 I* x
) E5 V0 t% ^# x8 [' }2 ~3 H  ?Pro5 的编译结果:
; a! y! q' K1 f3 E& X9 }" ^
) b, Q% `* j; e. ^( ]8 J      Code     (inc. data)   RO Data    RW Data    ZI Data      Debug  ( |% N0 A0 y9 j+ o' L$ a( v
* D$ m1 D+ |5 I  V1 Q; F7 C) X0 n
       932         32             16              4             96          0   Grand Totals
+ p# Q' y& b% b$ w7 `, ^+ r1 ?       932         32             16              4             96          0   Image Totals
0 J8 f' d5 u6 l# w7 Q5 f- e8 \2 B4 {/ O0 H3 `- s4 P
================================================================================
6 ?6 p+ h. f# ]: i& l3 x) w" N6 g7 Z5 y) a$ j$ K8 ?; O1 w* }
    Total RO  Size (Code + RO Data)                          948 (   0.93kB)
4 l$ ~7 m  h1 c8 O8 k9 A. t& t0 Q    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB)0 H( Q. W, p3 w1 c. V/ ~. z
    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)* {8 z. E1 ]& M2 t' b* [6 t

  b) c+ ?, z+ ^8 i0 K  v  P================================================================================
2 W& `3 v9 k2 H7 T+ l2 e3 t* m
0 c' G9 D9 r) q# S  YPro4与 Pro1 相比,只有 RW Data段 多了4字节。- Y0 F' ]* Z, j; [# |. z$ G

! u* Y8 U' X" I- ]1 S2 Q8 R在Pro5中,对于初始化为0的变量,其仍然放在了RW区。
% f2 b2 t0 Q9 l6 p3 `+ {4 Q- h6 l, {- S. f( x0 _4 ]6 X; |1 Q8 T
(3) ZI 段测试6 `9 G1 z) j6 _& v* ^2 l9 X

/ z: {) ]+ z! z2 GPro5 和 Pro1 之间的差别是一个未初始化的变量“a”,从之前的了解中,应该可以推测,这两个程序之间应该只有ZI大小有差别。5 ]" J( q, d$ J( Z' d, L7 k1 F

( F% P' ~& Q+ e7 [0 GPro5:
' z  V+ ]: U1 |; Y  G0 |1 \- V- m6 {
7 {" l3 p- A, }, G4 }+ G, t
   1: #include 0 w- E+ k! X* H) @
/ ]2 i: j- X. n3 U1 f4 g
   2: char a;3 Z( I$ w, [: _9 N& F) ]
% _' F2 h; {" Q8 l. Y
   3: void main(void)9 [: O( s+ v9 o3 o* C6 I2 e, J
/ Y# X5 Z3 T: Q4 a% F% e, m4 z& Z
   4: {
6 X$ p* L8 L5 h4 C" c% T* F$ x! c. L2 B
   5: ;( ~/ w' T# V8 O: M

4 N2 c4 U1 X9 L   6: }
1 `+ R/ ?4 F3 O5 v$ W0 H; v" h- yPro5的编译结果:
7 b( G! O; `8 V9 q
3 B! ~! X; t% l3 ]7 f      Code      (inc. data)   RO Data    RW Data    ZI Data      Debug    o+ L. {# \- O$ z+ Q- B  j
% L3 @& q+ P" Q
       932             32          16             4             96          0   Grand Totals
+ f5 k# s, l5 i% F       932             32          16             4             96          0   Image Totals
8 Z  s, m1 F/ ~- D( f- b* Q( {' m5 S( M# K
================================================================================% ^  w; a6 b& i" ^6 Q# L  `- }0 a

5 m! ?* |( z; g1 ^4 V* N    Total RO  Size (Code + RO Data)                          948 (   0.93kB)- ?0 v6 C5 U2 y/ A
    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB)
- q4 f1 n  ~& {) v" T' d    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)# L8 S9 D3 ^+ _: v$ S
! z7 X& C5 _: s2 C7 w+ i5 ?
================================================================================
, J2 G- r8 f; l3 c1 @/ u# w5 J) \6 g( P5 f# J7 S: t
实际情况是,未初始化的变量放在了 RW区,而不是ZI区。2 l6 e1 s0 v/ B% K

- l" ~, L1 |1 ?- N. W, Y: ~: g2 c' `, r四、总结; Q" K: Y% C* d5 \3 r2 s
通过上面的测试发现,ZI根本就没用到。这很费解。以下是Pro5的完整编译文件. _0 k9 J6 r2 M
- y4 u6 M) x8 }/ L$ H) ]
ARM Linker, RVCT2.2 [Build 349]* ~: j( j) \9 E. }0 q& N3 W

% Y# f/ c' I" ^4 S+ e================================================================================
7 y5 |0 @2 D+ ^0 o& D& y8 l, a/ z' H7 Z/ S, x  r& ?
Memory Map of the image) S' e) ^1 ]# a7 [* T
3 l3 s- T% X' q: p; I
  Image Entry point : 0x000080000 ~  D* d% X) h

1 t% c/ X5 }- x% ?" x7 y  Load Region LR_1 (Base: 0x00008000, Size: 0x000003b8, Max: 0xffffffff, ABSOLUTE)& `& V0 c6 \) |* I) N

' t4 T1 S5 t- C- R$ S    Execution Region ER_RO (Base: 0x00008000, Size: 0x000003b4, Max: 0xffffffff, ABSOLUTE)
, s2 A" e- _% m2 v! ]
) h" R5 w* _3 s! t% i) d    Base Addr    Size         Type   Attr      Idx    E Section Name        Object
) G' @, U" N6 A# Z7 n2 X- ^, R6 u3 G0 x9 f5 ^+ i
    0x00008000   0x00000008   Code   RO            6  * !!!main             __main.o(c_a__un.l)
  W4 I3 O! l: Q    0x00008008   0x00000038   Code   RO           26    !!!scatter          __scatter.o(c_a__un.l); a" o0 |) c7 _7 L( \* B
    0x00008040   0x0000002c   Code   RO           27    !!handler_zi        __scatter_zi.o(c_a__un.l)
& z/ \* `: s. N" h& @& R  G# ]    0x0000806c   0x00000010   Code   RO           11    .emb_text           lib_init.o(c_a__un.l)
! U2 a: P# \5 \" K* P# s    0x0000807c   0x00000004   Code   RO            1    .text               test.o
; e9 N4 |  S# ^5 d. {# C    0x00008080   0x00000048   Code   RO            7    .text               kernel.o(c_a__un.l)2 z; x- v+ I3 v: d* q& S
    0x000080c8   0x00000018   Code   RO            8    .text               sys_exit.o(c_a__un.l)
2 O. `" [" o7 D; x    0x000080e0   0x00000018   Code   RO
/ d6 ^/ t, I! \& x% n4 ^* B  i" `% C2 N3 k8 B
2 v0 Q9 ?9 c4 ]  P; J

, z/ r3 F, C! V1 r! l  M) s
4 b: |7 D: Y. q1 ~% B; T

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-10-26 18:33 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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