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

ARM程序结构&Image文件结构

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
1 Q" ?! g) D" b2 u7 z9 v; x1 v: O# }
说明:
$ `& X7 ~+ b, B5 w& \& `0 ~1、今天学习到ARM程序,于是到网上找了不少资料,发现真正有用的并不是很多。而且经过我的实际测试,与网上部分大神说的有不少出入。: ~% |& [' @* z9 N# u

4 d6 G$ v6 Y$ f" T4 O2 h5 q2、测试环境 WinXp  RVDS2.2的编译器和连接器1 A! \* B2 ?3 P: p) f9 K
3 C) E; U3 x; F" u6 G
3、关于测试使用的工具           ) S5 Z; f6 w( C. j4 E% u$ n
0 Y" _5 Z  J1 p# J
一、ARM程序的组成1 x9 _. w" X( w+ S$ u
: [2 O4 T! [' K) S0 i5 y+ t
此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的映像(image)文件。烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。, r( |0 A" Z4 T

5 e$ G5 a1 G1 o- _; D" C一个ARM程序包含3部分:RO,RW 和 ZI
. }- U+ V0 t0 c% b
! r* |; ]8 H. \* k7 URO:是程序中的指令和常量      ,ReadOnly    只读的代码段和常量
5 S; b6 m4 |) ?3 ^6 g+ N0 FRW:是程序中的已初始化变量  , ReadWrite  可读写的全局变量和静态变量' P7 z0 x8 C/ i' I( D
ZI:是程序中的未初始化的变量 , ZeroInit      RW段中要被初始化为零的变量的段(也就是说该段包含在RW内)7 n2 R" A$ y0 s2 B! f9 C
由以上3点在C语言中的表现:
( |4 X7 S( u8 A7 g
% v! _" A& z, _5 f1、C 中的指令以及常量被编译后是RO类型数据。, J( F9 h. U# M
2、C 中的未被初始化或初始化为0的变量编译后是ZI类型数据。(这点注意)7 Q. A, c) _0 G6 \* x/ n
3、C 中的已被初始化成非0值的变量编译后是RW类型数据。
8 |* W7 L& R, i. d- S/ N
: Q$ m7 W& g  N3 M# C* c4 I关于上面的这些,我将在下面,用实际的例子来说明。; c+ o. [/ A8 _# w& r- O' F5 G2 L& c4 {

) H6 O4 H, e1 V, [二、ARM映像文件的组成" p* T! b* e, @
6 `' W# {2 T* B9 s
        所谓ARM映像文件其实就是可执行文件,也成为image文件,又叫ELF文件。包括bin或hex两种格式,可以直接烧到rom里执行。在AXD调试过程中,我们调试的是 .axf 文件,其实这也是一种映像文件,它只是在bin文件中加了一个文件头和一些调试信息。
% g8 R( t; e5 g9 [! |4 W+ ?4 K. k( I8 x. J- f3 Z" t
        映像文件一般由域组成,域最多由三个输出段组成(RO,RW,ZI)组成,输出段又由输入段组成。所谓域,指的就是整个bin映像文件所处在的区域,它又分为加载域和运行域。我们输入的代码,一般有代码部分和数据部分,这就是所谓的输入段,经过编译后就变成了bin文件中RO段和RW段,还有所谓的ZI段,这就是输出段。
* t% [" N/ w: K' Q' }8 ]7 I0 Z) A# ~- ^# U; e6 Y6 G
       加载域:就是Image被静态存放的区域,一般就是指烧在flash中的整个bin文件;7 R; _& T$ z. S. K4 e+ w
# p) }  ~6 K6 b5 @5 T2 H
       运行域:通常是程序都是被搬到SDRAM中运行,该Image被搬在SDRAM里工作所处的地址空间就是运行域。3 q0 F2 m+ _5 g5 o4 @/ h

2 Q. I) y1 C& M( J/ B7 M, v2 r对于加载域中的输出段,一般来说RO段后面紧跟着RW段,RW段后面紧跟着ZI段。在运行域中这些输出段并不连续,但RW和ZI一定是连着的。ZI段和RW段中的数据其实可以是RW属性。4 x3 X6 ~) L& k1 M& D
/ M" ~  o# B' X& b0 l% K
        Image文件一般只包含了RO和RW数据。之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。* F0 }9 m$ z% T

$ G- W  @! F1 I! n) d% K+ }实际上,ROM中的指令至少应该有这样的功能:( U6 j) P8 V2 w$ m) z+ p0 O
        1、将RW从ROM中搬到RAM中。因为RW是变量,变量不能存在ROM中。
9 K5 |- H2 K$ P% P2 ~/ @* ^        2、将ZI所在的RAM区域全部清零。因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中
  T/ ?0 O3 G) H2 K在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。6 M- T- ~: \9 X0 v( e) O+ ?: I
/ m2 F' }% y$ z3 ]: y
三、实例测试
+ C- W6 b2 _$ o* v( W3 ~
. P% G8 \  K' x(1) RO段测试
6 s! p7 v; p& n) R& V3 z0 T& ^: z! W9 C& o
下面两段程序,他们之间差了一条语句,这条语句就是声明一个字符常量。因此按照我们之前说的,他们之间应该只会在RO数据中一条语句的大小。
: W0 y$ W4 J- l. `8 Z/ Y) U6 k9 V5 _& R" ?' O& x
Pro1:
0 M! S7 q& H# U
5 Z, L' \- w! {; S$ w   1: #include
* G& m# s5 H1 Q& U8 v* i
; d! E; P. b- q6 _   2: void main(void)" t) p4 N7 I) p  F, ~! R
2 Z2 O8 z( C. L; @) g& v
   3: {& H5 r: @6 Y3 R! b* |  [/ v4 @

5 c: m& R, O3 v# Y   4: ;7 a1 s/ ^3 v1 p7 f; d

+ x$ ]/ T" K( r6 @7 [6 \) w  R9 q   5: }
4 b7 H9 q" e6 W7 k" SPro2:( m. {# n0 p- m' [; l
: \/ t' n& U6 g. y  b* S3 ?
4 y  I. k1 `. E! R$ O% f& S+ y
   1: #include : O- b+ {  I3 o1 z5 l$ a4 J' x+ U
* W+ h) h8 K7 n% a; m
   2: const char ch = 2;  // 常量& `  K9 b8 S3 T; R- J- j
+ x( q9 p  \2 x4 s
   3: void main(void)$ w: J8 j7 q9 X) G8 x8 M6 |' q
: p! f$ b" M  f/ j' B$ n: Y
   4: {9 `+ o" i$ u$ Y/ m1 P
4 M$ {0 C  B. _7 `
   5: ;- c* w" H7 t: p7 y- i
" Y0 q, V, u1 w
   6: }7 ^5 y. n/ b' C) w: K
Pro3:: t( M$ ?3 o, A& }

- |' h) s& U* ^2 Y" {4 q* ~" g/ \/ w  `2 F
   1: #include
8 d+ f$ m7 W# s- Y+ X7 y
, K2 N4 u8 \. k/ V   2: const char ch = 2;; F$ {3 {! e8 Z# K7 q3 W

7 @& y1 p: ]+ {1 j' W7 L+ m   3: int main(void)
( [+ G& m! i$ _" l! J7 {8 A6 y# N/ }4 y
   4: {
& M' c; Y8 N; L3 U' u( R
1 p2 ]2 i5 U, J+ ?7 c4 D) ~4 l   5:     return 0;
) d% I. r8 {0 z* q9 ~: A  \
9 T: i  v8 u/ o7 D. |3 E  X! Y   6: }
8 s: ~  U* X: Q4 ?; p3 g$ APro1的编译结果:
4 M6 T4 U* L& D/ b& h0 i7 O5 U  c9 o  O% _( o, N
      Code   (inc. data)   RO Data    RW Data    ZI Data      Debug  
6 r' _. F  _8 c8 t  a" V7 G* k
: Q! r) p7 z0 m* Q# F      932      32           16          0         96          0   Grand Totals* s0 x/ S$ q* m9 Z+ n( j8 Q
      932      32           16          0         96          0   Image Totals
9 f! z2 ^( ?- M6 S' j4 t; ?3 O7 ^6 w; d  S" p
================================================================================
( T# W5 d4 P- F* U0 w8 E' p+ Q- n
# g$ @, [% I' P9 I  |" z, L6 U, m    Total RO  Size (Code + RO Data)                          948 (   0.93kB)3 B9 J! l4 h, U' y) C1 W6 g
    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB)
" y4 M6 `9 M! q% v: M' C/ ^    Total ROM Size (Code + RO Data + RW Data)        948 (   0.93kB)" M2 b& ~& M6 R/ _# `% D. x; x, y
2 \* D6 a' K, _6 ^; Y
================================================================================7 |; h" |$ I7 p' |' ^8 g( ]
# D, ?# D* i1 g) v
Pro2的编译结果:
; r2 J, s; W# L$ C3 d! O. \
; @- s5 W: ^1 F7 s" }( a      Code  (inc. data)   RO Data    RW Data    ZI Data      Debug  
' T9 w1 h- I, _: \3 v" A" t. W9 B6 J. n
      932      32         20          0         96          0   Grand Totals
# n! K2 {9 j, D! z/ E      932      32         20          0         96          0   Image Totals* W4 W5 G3 Z' k2 r

+ K$ V3 J8 z3 |1 l2 G. \3 K6 D================================================================================: u  k7 G0 `% \3 Y
" v4 J; [( @. l; |3 K; e
    Total RO  Size (Code + RO Data)                          952 (   0.93kB)
+ f$ ]" C/ X8 Q/ ?2 M; J3 Q' f    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB); m6 M0 B' O% u4 F9 \8 P, |( Y, o
    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)
( a- ^  O: F- @$ D
5 e% Y) o6 D& \6 b4 u4 O! p3 C! B. T================================================================================
* V& Q- o$ s& t& t
# {7 f" a" {2 ^* l( [Pro3的编译结果:: c& Z. P8 K( ^6 ^
+ p  d4 l1 j% t2 x$ x
      Code    (inc. data)   RO Data    RW Data    ZI Data      Debug  & a; u/ w4 [+ G1 P
$ v  w3 E- k+ N4 X4 N
      936         32             20              0             96          0   Grand Totals
/ w, W; F6 T  B+ H6 H      936         32             20              0             96          0   Image Totals3 W0 q7 l9 }! n( V0 g) \9 j

2 L3 x3 ~3 i- E' g================================================================================+ }9 ?5 |( ?8 K' ^6 p  h
$ U, `! x, R+ |: p% X; e2 `2 ^
    Total RO  Size (Code + RO Data)                          956 (   0.93kB)
- e8 M& l6 q  e6 d0 z    Total RW  Size (RW Data + ZI Data)                     96 (   0.09kB)
! U  H& c- Q* D  F- Z  ]    Total ROM Size (Code + RO Data + RW Data)        956 (   0.93kB)
4 f# ]# G  s5 [% P
5 P- ]- _0 S0 K7 s================================================================================
. i1 N0 b* k+ P
- M) Z" N  u& U: V! ]6 S: r由上面的编译结果(尤其是加红部分)可知:常量被放在了 RO段中,验证第一点。增加一条语句时,Code部分大小增大。0 ]* N! K$ r* g& K; }

( \- Q5 t* _* Z  S. e; p" {, X(2) RW段测试
4 z7 r1 }/ p$ r+ R
" v+ S+ }* p) O2 [Pro4和Pro1 之间只相差一个“已初始化为非零的变量“,按照之前所讲的,已初始化的变量应该是算在RW中的,所以两个程序之间应该是RW大小有区别。
3 g' A. k  u) d0 u% G3 e) ^9 L3 R$ e* ^+ N( v- \
Pro4:
( p, w% ?: Z8 \1 w! \% K3 G  E6 _# h; y. C9 l

3 g; p0 ~/ m8 ]5 p6 D  r- w, K   1: #include 4 O3 W4 u9 Z  v9 Y( [' \, }. u

7 x/ S- C3 e0 A   2: char a = 5;
7 J, l4 h4 A. O- y$ A# X) O6 D5 k$ z4 Q
   3: void main(void)+ \" D, d7 R. W
( v4 k+ D% B9 |- d
   4: {/ w. d( N7 J+ S' _0 D0 x

! z: X  n% V, L: J, R   5: ;
! q; O: l2 \& [3 M; Y3 S, w9 \- [
   6: }
: `* }: j0 X. R& |Pro5:
+ B! A2 P/ `* p1 I' P& b6 P) z2 G6 Q; h! h; W7 g$ s$ z/ J

% N4 u) |, t8 m- Y4 f) y   1: #include $ R$ q9 l3 X6 Z; q
( q. k$ l# O* x8 _4 F. n6 G7 \
   2: char a = 0;+ \  ^5 e! W' B: \# i, ~, N) i
4 |* ~! D$ }. j
   3: void main(void)
" {* ^3 L1 y3 l) b2 j* g
# m6 P; M; U! B) e8 x   4: {1 m  {; e: b0 F9 S4 l
, g5 D- W3 W" z" n
   5: ;
0 K5 L5 X* o% r& J- H* u2 a: L
/ W& f- W3 f% Y5 N: [( b   6: }
3 U. P+ f* j& S. F, I3 }Pro4 的编译结果:
4 `3 K, {1 ?, Y  W, H7 G; B) Y9 C% Q& @0 ~( x9 t' J' ?& l: d# ~+ Y
      Code     (inc. data)   RO Data    RW Data    ZI Data      Debug  
' t) t; B/ E% c& M* G# D  r3 a% e( O$ p0 M0 ~* H3 c( H: n
       932         32              16            4             96          0   Grand Totals
6 b  H$ e- Z9 ~  m! o- X0 [; G       932         32              16            4             96          0   Image Totals+ ^  l. c2 ?# @/ k* h
6 v1 z7 M' `  N# P, i0 I( e( E
================================================================================
% ]& @7 [% o  H% F% @3 A3 E0 o& U
    Total RO  Size (Code + RO Data)                          948 (   0.93kB)
* C& \) _* z9 |& [, F+ t. z& l5 n    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB)
9 Y( T/ h1 H3 h8 B6 S    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)
6 k- K+ ~6 D; w1 N3 k& J. d* a# ?$ F
3 Y  ~+ a- V8 \) t% D================================================================================  n. y" ?$ D6 |+ b( `# U4 T1 X; N! Z( i

+ W) q* _' c3 j2 `, P/ QPro5 的编译结果:
9 a( e# r; h" [) z# U" X) O
7 r6 @/ K4 m: D  ]! }: n      Code     (inc. data)   RO Data    RW Data    ZI Data      Debug  9 I7 Y, j2 L" q% x4 T) t  x
# a& M9 y' x; K, L4 B
       932         32             16              4             96          0   Grand Totals. H. m' v- M+ p4 B+ W0 `
       932         32             16              4             96          0   Image Totals
& _& q1 a7 q0 W, @9 Z2 F
8 C5 z  M0 V' Q0 ^: ]================================================================================  p* Y) F+ i9 P6 Y4 |7 c4 h
' q+ z' U) K+ A( l/ P
    Total RO  Size (Code + RO Data)                          948 (   0.93kB)
7 T- c. F! r$ t; @! f    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB)# V8 k" h& r  M8 G! m/ _3 B
    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)$ T% d! _3 J* K' \# h
2 V3 _5 Z5 y8 B. v, ?* p
================================================================================; `) B% N" `) x" G- B8 k
0 d+ l' O) _$ k2 [+ ]
Pro4与 Pro1 相比,只有 RW Data段 多了4字节。
  u8 |" |& F( F. s' \( g$ I- U5 K% n
在Pro5中,对于初始化为0的变量,其仍然放在了RW区。
# n; M, p2 r7 F. g9 A% g6 O* j5 E, q: d1 M% X, {
(3) ZI 段测试4 c3 @" M8 Z5 u! e" \. q( k

% n& N/ `# ]; |8 S/ L. NPro5 和 Pro1 之间的差别是一个未初始化的变量“a”,从之前的了解中,应该可以推测,这两个程序之间应该只有ZI大小有差别。
% e% f+ X( _, i) J. B5 I& n7 v4 E! e+ x# h" `+ J( \
Pro5:
! k9 P- _- o: o; |- N( g- F3 I4 @0 m! J  G" T

+ b& m- j1 I6 F- m( Q! e0 X   1: #include
- y' d- J/ M* Q6 n
9 K- ^3 ?# ?) ]+ z4 y   2: char a;
6 ]6 R. D  u# @/ c# e  t  Z
( n% E, q7 E1 S( d/ k. F9 u   3: void main(void)
: M- {+ z2 v6 P6 \) @4 s. P+ {7 Y0 k
   4: {
# c5 l% k. r) n" B# z' N; t( @" B- v: ]: |" K. b
   5: ;* `7 p1 T% q7 y: F; J# v

" t% C8 l, Q. Y: ]1 B; q8 z   6: }
" K  e  F4 e" a# Z$ OPro5的编译结果:
8 H- @0 o6 o% _
9 R  c1 ^3 ~3 Y( ^/ C) Y0 P9 K      Code      (inc. data)   RO Data    RW Data    ZI Data      Debug  ! y5 ~3 |. j3 c" F3 e+ @3 K

% t4 _: X) s4 n& W7 W% T       932             32          16             4             96          0   Grand Totals) L$ N3 _. d: t0 W! }6 v5 _
       932             32          16             4             96          0   Image Totals/ ^: B. a! v( Z4 j! Q! i

6 b7 s6 m4 h: t" h================================================================================7 j* `. ^4 `7 x  [6 {

3 C. I1 r5 |0 W2 G    Total RO  Size (Code + RO Data)                          948 (   0.93kB)6 D/ n& `9 F: |7 E9 ]: T3 {; w
    Total RW  Size (RW Data + ZI Data)                     100 (   0.10kB): A- T, X6 s3 A
    Total ROM Size (Code + RO Data + RW Data)        952 (   0.93kB)
+ H' N# L$ y- Y1 n% g
9 W, d, I' l8 ]$ U6 n================================================================================
3 V0 {1 B$ h$ a" |
8 z7 L& B6 _/ s0 C" M# x% c实际情况是,未初始化的变量放在了 RW区,而不是ZI区。
, Z% O/ q$ S5 |& Y. X
; a- y/ L( s; o" g, R. k四、总结4 k! l  P3 M1 \- x3 m
通过上面的测试发现,ZI根本就没用到。这很费解。以下是Pro5的完整编译文件" P& h+ r0 J6 A, a+ M

+ ^) J! B* m* Z# fARM Linker, RVCT2.2 [Build 349]
: h3 }( x) Q  s: E; c( I# m6 h1 X9 S5 H& j
================================================================================
) B; n' S, p0 B5 S5 X( N0 @' X: v
" d- U" D* p% F) s# ]- q6 D) dMemory Map of the image& j2 m* M, ?( X7 H8 n! b& R/ r. Y

! }0 _' }3 H; X4 Y  S1 ?, D8 ^  Image Entry point : 0x00008000
. H/ o& V- p/ M  h. b, y' h+ t# T0 y0 ?  V$ w  ?/ q9 T
  Load Region LR_1 (Base: 0x00008000, Size: 0x000003b8, Max: 0xffffffff, ABSOLUTE)/ [& c) z1 B1 [0 X

, V" I/ f- h7 [* H4 n& ~    Execution Region ER_RO (Base: 0x00008000, Size: 0x000003b4, Max: 0xffffffff, ABSOLUTE)- q1 M( ^# |9 Z! a$ q) D! P; Y- I

# v1 t7 a# K" k2 _$ a    Base Addr    Size         Type   Attr      Idx    E Section Name        Object
* k9 F5 d8 \! r1 X9 p" N* L- J' U6 }/ {$ E, F
    0x00008000   0x00000008   Code   RO            6  * !!!main             __main.o(c_a__un.l)
8 Q1 f+ i% Z, Z. p" x    0x00008008   0x00000038   Code   RO           26    !!!scatter          __scatter.o(c_a__un.l)
5 ?. B* w; F: j+ R0 O; ~    0x00008040   0x0000002c   Code   RO           27    !!handler_zi        __scatter_zi.o(c_a__un.l)
! n3 U% y0 ]5 h' W2 F    0x0000806c   0x00000010   Code   RO           11    .emb_text           lib_init.o(c_a__un.l)
# L" O5 @, {6 l! F    0x0000807c   0x00000004   Code   RO            1    .text               test.o
' n4 c) G" v4 L; P    0x00008080   0x00000048   Code   RO            7    .text               kernel.o(c_a__un.l)
, X. m( Y. {/ W3 b* U& ?    0x000080c8   0x00000018   Code   RO            8    .text               sys_exit.o(c_a__un.l)
- v% H. s3 |' Q8 o' K0 z    0x000080e0   0x00000018   Code   RO ( U, |2 w! b: A1 H; \  @

5 N7 e4 Y* D0 |3 P
3 Q* l- d8 K% _5 v0 H; L" M" t  W8 q! C5 e

$ d, E. _& j* P+ y2 I

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-29 07:29 , Processed in 0.078125 second(s), 23 queries , Gzip On.

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

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

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