单片机二进制文件分析:IAP程序跳转与PC指针指向问题解析

bin文件分析

  • bin、map、反汇编文件
  • bin文件简介
  • msp文件简介
  • 反汇编文件简介
  • 怎么分析bin文件
  • 分析bin文件
  • keil生成bin、map和反汇编文件
  • bin 和 反汇编文件
  • map文件
  • 结合程序分析bin文件
  • 从map和反汇编中分析bin文件
  • 总结
  • bin、map、反汇编文件

    bin文件简介

       .bin 文件就是二进制文件(binary file),这种文件只包含机器码。所有的数据都是机器可以执行的指令码、指令参数或者常量数据,不包含其它调试信息。加载到内存或者支持XIP(就地执行)的存储器中规定好的加载地址之后直接从规定好的运行地址开始运行即可。
      例如单片机中烧写的都是 .bin 文件,以STM32为例,其片内Nor FLASH的起始地址也是代码的加载(烧写)地址为 0x08000000 。上电复位或者手动复位之后,程序计数器PC指向单片机的复位异常的中断向量地址 0x08000004 的位置,单片机从复位开始运行。

      上图就是一个bin文件的内容节选,在上图的bin文件中左侧的 Address 表示的是现在地址的相对位置,一般情况下我们都是将斌文件下载到地址 0x08000000 中,所以上文提及的 0x08000004 内存中存储的是上图红色框的内容 0x080001ad (这是一个小端存储的单片机)

    msp文件简介

      在单片机开发中,.map 文件是一种编译过程中的输出文件,通常由编译器在完成代码编译后生成。.map 文件包含了程序中函数和变量的内存布局信息,这些信息描述了程序在内存中的位置和大小。
      这是一个函数、变量在单片机中存储的绝对文件,可以通过该文件快速定位到单片机中某一个变量的存储地址或者某一个函数的入口地址。通过查看 .map 文件可以确定哪些变量或函数占用了大量的内存,从而进行相应的优化。在链接阶段,.map 文件用于确定程序中各个函数和变量的最终地址。链接器使用 .map 文件来确定如何将分散的代码段和数据段整合到一起,以形成一个可执行程序。对于逆向工程和二进制分析.map 文件可以提供有用的信息,因为它们描述了程序如何在内存中布局,这对于理解程序的执行流程和结构非常有帮助。

    反汇编文件简介

      单片机中的反汇编文件是一种将机器语言代码转换为汇编语言代码的工具。可以通过反汇编文件在调试过程中定位和解决问题。通过查看反汇编文件可以了解代码的执行过程,并确定可能出现问题的位置。可以使用反汇编文件帮助分析单片机的性能瓶颈。通过查看反汇编文件可以了解代码的执行时间和执行效率,从而确定需要优化的部分。通过查看反汇编文件,可以帮助对bin文件中的指令代码进行识别。

    怎么分析bin文件

      要想对二进制文件进行分析,就必须接住.map文件和反汇编文件,这两个文件可以帮助我们快速分析和理解。
      通过结合.map文件可以帮助我们快速定位代码和数据的地址,这样可以在.bin文件中查找到对应的内容,但是.map文件没有帮助我们理解遇到内存中是指令的数据类型,这时就需要反汇编文件帮助我们理解了。

    分析bin文件

    keil生成bin、map和反汇编文件

      在keil中一般只会自动生成一个.map文件,但是这个文件内容非常多,大部分对于我们分析.bin文件没有帮助,所以需要对其生成的内容进行修改。而.bin文件和反汇编文件的生成需要使用一些命令来实现。

    bin 和 反汇编文件

      在keil的 Opentions for Target ->> User ->> After Build/Rebuild 中输入如下图所示的内容即可生成 二进制 bin(.bin) 文件和 反汇编(.asm) 文件夹。

    注意:完成编写内容后一定要在 Run #x前面打上勾,并且编译一次项目才会生成

      编写完成并且编译之后,可以在工程目录下找到对应的bin 和 asm 文件。

    map文件

      在keil的 Opentions for Target ->> Listing 中选中 Linker Listing,并且按照如下图配置只选中:

    注意:完成以上内容后一定要重新编译一次项目才会生成,并且生成文件在工程目录下的 Listings 文件夹中

    结合程序分析bin文件

      在.bin文件的开头有如下内容:

      从上面对bin文件的简介中提到单片机复位之后 PC 指针将指向 0x08000004 (这是复位中断的地址),那么前面跳过的4个字节是什么东西呢,接着我们打开单片机的汇编代码:

      其实在单片机中已经指定了以上中断服务的入口地址,我们所编写的中断服务函数其实就是将中断服务函数的入口地址存储在这些已经确定的中断服务地址中,所以前面忽略的4个字节的内容其实就是栈(SP指针)顶地址,具体可以查看启动过程详解。

    注意:前四个字节是栈顶地址,不是函数的入口地址(不能让PC指针指向这里),所以PC指针是在单片机复位以后自动指向 0x0800004

    我这个单片机一共使用了101个中断,所以前194字节都应该是中断的内容,这是我们无法改变的,也就是下图红色框所画出来的都是。

      0x08000004 地址下面存放的数据内容是上图中的 0x080001ad ,这是一个地址内容,这个是一个函数入口(PC指针指向了这里)。

    从map和反汇编中分析bin文件

      上面是从程序中的分析,再结合.map文件进行分析时就会非常方便了,下图就是我们.bin文件中的前194字节的服务地址。

      接着看 0x08000004 地址下面存放的数据内容是上图中的 0x080001ad ,在上图中我们并没有直接看到 0x080001ad 这个地址,这时我们需要对.bin文件和反汇编文件进行结合分析。


      其实从上图可以看出 0x080001ad 这个地址里面的内容是一个16位的指令,所以在.map文件中就对应于地址 0x080001ac 。

      在进入服务中断服务中,你会发现有一个在所有文档中找不到的函数 __main 。

      这个函数可以参考文章STM32启动详细流程之__main,结合反汇编文件进行分析可以快速理解。

      对于.bin而言最具有分析价值的地方就在于开头的地方。

    总结

      对于使用IAP而言,在做程序跳转时 PC 的指针应该指向应用程序相对地址的 0x00000004 ,0x00000000存储的是栈顶指针,这一点非常重要。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机二进制文件分析:IAP程序跳转与PC指针指向问题解析

    发表评论