• 代码中函数、变量、常量 / 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("子函数 局部变量 : 
    ");
            printf("local4 : %p 
    ", &local4);
            printf("local5 : %p 
    ", &local5);
            printf("local6 : %p 
    ", &local6);
    
            printf("子函数 指针变量 : 
    ");
            printf("p2 : %p 
    ", p2);
    
            printf("全局变量 : 
    ");
            printf("global1 : %p 
    ", &global1);
            printf("global2 : %p 
    ", &global2);
            printf("global3 : %p 
    ", &global3);
    
            printf("子函数 静态变量 : 
    ");
            printf("static4 : %p 
    ", &static4);
            printf("static5 : %p 
    ", &static5);
            printf("static6 : %p 
    ", &static6);
    
            printf("子函数地址 : 
    ");
            printf("function : %p 
    ", 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("主函数 局部变量 : 
    ");
            printf("local1 : %p 
    ", &local1);
            printf("local2 : %p 
    ", &local2);
            printf("local3 : %p 
    ", &local3);
            printf("const1 : %p 
    ", &const1);
    
            printf("主函数 指针变量 : 
    ");
            printf("p1 : %p 
    ", p1);
    
            printf("全局变量 : 
    ");
            printf("global1 : %p 
    ", &global1);
            printf("global2 : %p 
    ", &global2);
            printf("global3 : %p 
    ", &global3);
    
            printf("主函数 静态变量 : 
    ");
            printf("static1 : %p 
    ", &static1);
            printf("static2 : %p 
    ", &static2);
            printf("static3 : %p 
    ", &static3);
    
            printf("字符串常量 : 
    ");
            printf("char_p : %p 
    ", char_p);
    
            printf("主函数地址 : 
    ");
            printf("main : %p 
    ", demo_main);
    
    
            printf("= = = = = = = = = = = = = = = 
    ");
    
            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

  • 相关阅读:
    4. Dictionary HashTable
    5.1. ISet HashSet
    5.2.ISet SortedSet
    6.1. String
    6.2. Encoding
    2.1. List
    1. 基础类型
    0.源代码代码分布情况
    0.2.比较接口Default
    Android获取应用启动时间
  • 原文地址:https://www.cnblogs.com/mylinux/p/4135088.html
Copyright © 2020-2023  润新知