zoukankan      html  css  js  c++  java
  • Keil开发的ARM程序main函数之前的汇编分析

    Keil开发的ARM程序main函数之前的汇编分析

    ——BIN文件中RW段的数据移动

    系统平台:

    STM32系列STM32F103ZE,512KB内部FLASH,64KB片内存储;

    FLASH地址范围0x0800 0000 ~ 0x0808 0000,用于存放代码;

    片内存储地址范围0x2000 0000 ~ 0x2001 0000,用于存放数据;

    Cortex-M3上电后来到复位中断(已将前4个字节的值存入MSP堆栈指针),转到__main标号,完成RW段的移动、ZI段的初始化,建立堆栈,初始化库函数,然后跳转到main函数,开启C程序之旅,执行流程如图1所示。

    图1 main函数之前的汇编程序执行流程图

    本文主要讨论RW段的移动,RW段就是程序中赋了初值的变量,它的搬移我看到过两种方式。在BIN文件中,RO段和RW段之间有8个双字的Region$$Table,4个双字一组,分别用于完成RW段的搬移和ZI段的初始化。

    (1)       __scatterload_copy来完成

    此时RW段的内容保存到内存开始的地方,本文中是0x20000000,用这一方式完成后,内存中存放的不是RW数据的内容,而是一个地址。这个地址是在FLASH中,即指向了其在RO段的地址,实际的内容是在RO段中。

    (2)       通过__uncompressed1实现

    RW是程序中初始化的变量,但是这些变量有可能初值是0,因此为了节省空间,实际在BIN文件中RW段是压缩过的。调用__uncompressed1解压缩RW段的数据内容,并将其保存到内存开始的地方。

     

    图2 BIN文件中压缩RW段内容

       图2是BIN文件中RW段的数据内容,影印部分显示,大小是164字节。其中0x0001 C72C前面8个双字的内容是Region$$Table,将其列出如下。

    0x0801 C72C         BIN文件中RW段的开始地址

    0x2000 0000          RW段要存放到RAM中的地址

    0x0000 0334          要存放到RAM中的RW段数据大小

    0x0800 0184          执行函数__scatterload_copy或者__uncompressed1的地址

    上面4个双字完成RW段的搬移。

    0x0801 C7D0        BIN文件的末尾,ZI段的开始

    0x2000 0334          ZI段放到RAM中的起始位置

    0x0000 F4BC        ZI段的大小

    0x0800 01E0         执行函数__scatterload_zeroinit的地址

    这4个双字完成ZI段的初始化。

     

    图3 RW段内容解压缩后在RAM中排布

    将BIN文件中RW解压缩以后(这个解压缩从反汇编可以看到,但是没有看明白),实际内容如图3所示,大小变为820个字节,该补0的地方都已经补足了。

  • 相关阅读:
    ui5 call view or method from another view
    vuejs helloworld
    vuejs v-model
    vuejs v-bind
    vuejs on
    vuejs fatherandson
    vuejs scope
    vuejs keep-alive
    VLAN虚拟局域网
    网线的制作
  • 原文地址:https://www.cnblogs.com/fozu/p/3614068.html
Copyright © 2011-2022 走看看