代碼中函數、變量、常量 / bss段、data段、text段 /sct文件、.map文件的關系[實例分析arm代碼(mdk)]


函數代碼://demo.c

#include<stdio.h>
#include<stdlib.h>

int global1 = 0, global2 = 0, global3 = 0;

void function(void)
{
        int local4 = 0, local5 = 0, local6 = 0;
        static int static4 = 0, static5 = 0, static6 = 0;
        int *p2 = (int*)malloc(sizeof(int));

        printf("子函數 局部變量 : \n");
        printf("local4 : %p \n", &local4);
        printf("local5 : %p \n", &local5);
        printf("local6 : %p \n", &local6);

        printf("子函數 指針變量 : \n");
        printf("p2 : %p \n", p2);

        printf("全局變量 : \n");
        printf("global1 : %p \n", &global1);
        printf("global2 : %p \n", &global2);
        printf("global3 : %p \n", &global3);

        printf("子函數 靜態變量 : \n");
        printf("static4 : %p \n", &static4);
        printf("static5 : %p \n", &static5);
        printf("static6 : %p \n", &static6);

        printf("子函數地址 : \n");
        printf("function : %p \n", function);
}

int demo_main(int argc, char **argv)
{
        int local1 = 0, local2 = 0, local3 = 0;
        static int static1 = 0, static2 = 0, static3 = 0;
        int *p1 = (int*)malloc(sizeof(int));
        const int const1 = 0;
        char *char_p = "char";

        printf("主函數 局部變量 : \n");
        printf("local1 : %p \n", &local1);
        printf("local2 : %p \n", &local2);
        printf("local3 : %p \n", &local3);
        printf("const1 : %p \n", &const1);

        printf("主函數 指針變量 : \n");
        printf("p1 : %p \n", p1);

        printf("全局變量 : \n");
        printf("global1 : %p \n", &global1);
        printf("global2 : %p \n", &global2);
        printf("global3 : %p \n", &global3);

        printf("主函數 靜態變量 : \n");
        printf("static1 : %p \n", &static1);
        printf("static2 : %p \n", &static2);
        printf("static3 : %p \n", &static3);

        printf("字符串常量 : \n");
        printf("char_p : %p \n", char_p);

        printf("主函數地址 : \n");
        printf("main : %p \n", demo_main);


        printf("= = = = = = = = = = = = = = = \n");

        function();

        return 0;
}

 

函數打印情況,並結合sct文件、init.s分析:

;;init.s 
;The location of stacks
UserStack  EQU    (_STACK_BASEADDRESS-0x3800)    ;0x33ff4800 ~ 0x33ff5800
SVCStack    EQU    (_STACK_BASEADDRESS-0x2800)    ;0x33ff5800 ~
UndefStack    EQU    (_STACK_BASEADDRESS-0x2400)    ;0x33ff5c00 ~
AbortStack    EQU    (_STACK_BASEADDRESS-0x2000)    ;0x33ff6000 ~
IRQStack    EQU    (_STACK_BASEADDRESS-0x1000)    ;0x33ff7000 ~
FIQStack    EQU    (_STACK_BASEADDRESS-0x0)    ;0x33ff8000 ~

 

主函數 局部變量 :         //運行時,UserStack棧中,map文件里面沒有
local1 : 33ff56e4    
local2 : 33ff56e0 
local3 : 33ff56dc 
const1 : 33ff56d8 
主函數 malloc指針變量 :   //運行時,堆中,map文件里面沒有 
p1 : 37000020        //_init_alloc(0x37000000,0x38000000-8); 
全局變量 :                 //Data     demo.o(.data)      [rw]
global1 : 322000a8 
global2 : 322000ac 
global3 : 322000b0 
主函數 靜態變量 :         //Data     demo.o(.data)      [rw]
static1 : 322000c0 
static2 : 322000c4 
static3 : 322000c8 
字符串常量 :             //Code demo.o(.text)   [ro]
char_p : 32013b28         
主函數地址 :             //ARM Code  demo.o(.text)  [ro]
demo_main : 32013a10         
= = = = = = = = = = = = = = = 
子函數 局部變量 :         //運行時,map文件里面沒有
local4 : 33ff56c8 
local5 : 33ff56c4 
local6 : 33ff56c0 
子函數 指針變量 :         //運行時,map文件里面沒有
p2 : 37000030 
全局變量 :                 //Data     demo.o(.data)      [rw]
global1 : 322000a8 
global2 : 322000ac 
global3 : 322000b0 
子函數 靜態變量 :         //Data     demo.o(.data)      [rw]
static4 : 322000b4 
static5 : 322000b8 
static6 : 322000bc 
子函數地址 :             //ARM Code  demo.o(.text)  [ro]
function : 3201381c 

sct 、 map文件分析:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_ROM1 0x32000000 0x00200000  {    ; load region size_region
  ER_ROM1 0x32000000 0x00200000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  
  ;const data[ro] and code
  ;Symbol Name                      Ov Type     Size        Object(Section)
  ;RESET                            Section     532         init.o(RESET)
  ;IsrIRQ                           ARM Code    0           init.o(RESET)
  ;static U16 ReadStatus            ARM Code                nand.o(.text)
  ;static void WriteRawRCBySPI1     ARM Code                nand.o(.text)
  ;static const U8 exchang_right    Data                    des.o(.constdata)
  ;__ENTRY                          ARM Code    0           init.o(RESET)
  ;void DelayMs                     ARM Code    40          common.o(.text)
  
  RW_RAM1 0x32200000 0x04000000  {  ; RW data   0x3220002c .ANY (+RW +ZI)//可更改的變量
  }
  
  ;rw data + bss                   
  ;static char IcCardSnrFound[7]    Data                    execmd.o(.data)
  ;static U8 s_Buf[64][2048]        Data                    nfblack.o(.bss)
  ;int grDebugCom                   Data                    common.o(.data)
  ;u8 downloadbuf[192*2048]         Data                    fireupdate.o(.bss)
  ;struct USB_DEVICE_DESCRIPTOR descDev     Data            usbsetup.o(.bss)

  RW_IRAM1 0x40000000 0x00001000  {
   .ANY (+RW +ZI)
  }
}
 
bss段,代碼段及數據段的區別[1]:
bss和data的區別:
    全局的未初始化變量存在於.bss段中,具體體現為一個占位符;
    全局的已初始化變量存於.data段中;

    .bss是不占用.exe文件空間的,其內容由操作系統初始化(清零);
    而.data卻需要占用,其內容由程序初始化。

    若這樣定義一個全局變量:int g_inBss[9] ;
    則它在.bss段,這里占用占位符的空間。

    若這樣定義一個全局變量:int g_inData[9] ={1,2,3,4,5,6,7,8,9};
    則它在.data段,程序占用數組全部大小的空間。

bss和data的聯系:
    都在rw區域;
    bss段在運行起來成為進程之后,占的空間大小和data就相同了。
代碼段:代碼段(code segment/text segment)通常是指用來存放程序執行代碼的一塊內存區域。這部分區域的大小在程序運行前就已經確定,並且內存區域通常屬於只讀
(某些架構也允許代碼段為可寫,即允許修改程序)。
在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。
代碼段是存放了程序代碼的數據,假如機器 中有數個進程運行相同的一個程序,那么它們就可以使用同一個代碼段。
 

參考:

1、  bss段,代碼段及數據段的區別

http://blog.163.com/starjj_embeded/blog/static/2045000512012213113440344/

 2、BSS段、數據段、代碼段、堆與棧

http://www.cppblog.com/prayer/archive/2009/08/17/93594.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM