STM32在KEIL平台反汇编代码分析

汇编语言的重要性与实践
本文探讨了汇编语言在现代编程中的作用,包括提升性能、辅助问题诊断及加深对硬件的理解等方面。通过实例演示了如何在KEIL环境中阅读和理解C语言编译后的汇编代码,展示了汇编在实际应用中的价值。

  不同的平台的汇编代码是不一样的,最早的汇编在50年代就发明了,比很多人的父母的年龄都大,老掉牙,不用学习怎么写汇编。一个公司有一个人知道怎么写汇编就够了。但要学习读汇编

  • 为什么学习汇编?

      1 性能 直接翻译为机器语言,性能最高。优秀的C语言效率只能达到汇编的80%左右。其他高级语言跟汇编一比差得更远。语言越高级性能越差。很多bootloader和BIOS用汇编写,汇编操作的是电脑,手机刚刚上电时,硬件和初始化的那些命令,它们的性能的要求比较高,效率高开机速度更快。
      2 分析问题。个人认为,编程人与机器对话,我们写C,写JAVA,但是电脑并不认识这些语言,电脑只认识0和1;所以需要一个人来翻译这些语言,这个翻译官就是编译器,但是编译器不能百分之百准确的表达程序员的意思,也就是所谓的翻译有反义。例如,编译器为了性能好一点,可能会优化变量和语句,这个过程可能好心办坏事,把有用的操作优化了。因此只有看懂一些汇编语句,才能分析程序真正执行的流程。在问题难以定位的情况下,汇编可能是分析问题的最后一根稻草。
      3 帮助理解硬件。有些学校的单片机课程是以汇编进行教学的,主要原因就是汇编更贴近硬件。不过我不赞成这种做法,C语言能快速做出一点东西,有利于学生在放弃之前,增加成就感,好坚持下去。但是汇编确实更贴近硬件,

  • 如何在KEIL下阅读汇编

      按d进入debug模式,在view下选择disassembly window
    这里写图片描述
      看光标,c文件下指向了main函数的第一行。
      汇编窗口也指向了对应的语句。但是,在执行C语言的第一行之前,仍然有许多操作要做,比如变量放在哪?在哪里调用了main函数等,这些操作都被集成开发环境IDE给封装起来了。我们必须知道,在执行main函数之前,有许多事情要做,只不过,初学的时候不必理会。

      以下是C语言源码,功能是点亮LED.

//main.c
#include <stm32f10x.h>  
int main(void)
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
    GPIOB->CRL &= ~(0xf<<(1*4));
    GPIOB->CRL |= 0x2<<(1*4);     
    GPIOB->ODR &= ~(1<<1);
    return 0;             
}
//main.h
#define RCC_APB2ENR (*(unsigned int *)0x40021018)
#define GPIOB_CRL (*(unsigned int *)0x40010c00)
#define GPIOB_ODR (*(unsigned int *)0x40010c0c)

  汇编窗口往上翻,确实很多语句。
  先看这几行代码的汇编
这里写图片描述
  先说最常用的两句汇编

LDR r0,[r1]    r0 = *r1
STR  r0,[r1]    *r1 = r0
MOV r0r1    r1->r0拷贝

  资料参考,可以搜索
http://blog.youkuaiyun.com/tanyouliang/article/details/6767011
http://blog.youkuaiyun.com/a1875566250/article/details/8507168
这里写图片描述
  从内存0x0800 017c的32位数据拷贝到r0
  r0 = * 0x0800 017c
  我们看到的 1000 4002其实 就是0x4002 1000。这里边有个知识点叫做大小端模式,以下简单讲解,不能理解就记住
这里写图片描述
  这个数据是在地址是这么存放的
  7C 7D 7E 7F
  00 10 02 40
  实际数据是0x4002 1000
  * 0x0800 017c=0x4002 1000
  然后r0的值+0x18也就是24 因为这个是第6号(第6号就是第7个的意思)元素
  得到r0 = *0x4002 1018,r0的值由一个地址,变成了地址所存放的数据。
  然后是或0x08操作,结果再复制给r0,*0x4002 1018 |=0x08
  给r1分配地址,这个地址也是0x4002 1000, r1 = *0x4002 1000
  把r0存放的值,(不是r0的地址,)存到r1+18的空间上
  *(r1+0x18) = r0
  *0x4002 1018 = (*0x4002 1018 |=0x08)
  *0x4002 1018|=0x08
  最终结果:地址4002 1018的数,执行了或0x08的操作

  再分析下一句
这里写图片描述
  前两句给r0分配空间,r0 = *0x4001 0c00
  然后用BIC清除数据位,把4-7位清零,结果再赋值给r0
  *0x4001 0c00 &= ~(0xf0)
  r1 = *0x4001 0c00
  *0x4001 0c00 &= ~(0xf0)

  剩下的不再详细分析,直接给答案
这里写图片描述
***0x4001 0c00 |= 0x20
0x4001 0c0c &= ~(0x02)*

  经过层层抽丝剥茧,可以看到C语句被翻译成了意料之中的汇编语句。或者说,经过分析这些汇编语句,我们发现,自己的意图被机器准确的理解了。再然后就是汇编变成机器码,这个过程本篇不讨论

<think>好的,用户想知道如何在STM32H750上生成反汇编文件。我需要先回忆一下STM32开发的相关工具和方法。首先,STM32通常使用Keil、IAR或者GCC工具链进行开发,生成反汇编文件的方法可能因工具而异。 接下来,我应该分步骤考虑不同开发环境下的操作。比如,在Keil中,可能需要在编译后通过命令行工具fromelf来生成反汇编。而如果是使用GCC的话,可能需要用objdump工具来处理生成的elf文件。此外,STM32CubeIDE基于GCC,所以方法可能类似。 用户可能对命令行工具不太熟悉,所以需要给出具体的命令示例。例如,使用arm-none-eabi-objdump命令,并说明如何找到该工具的位置,尤其是在Windows系统中可能安装路径比较复杂。 另外,需要考虑用户的实际操作步骤,比如编译生成elf文件后,如何在IDE中配置生成反汇编的选项,或者手动执行命令。还要提醒用户反汇编的作用,比如调试或分析代码大小,以及需要注意的架构和工具链匹配问题。 需要验证这些步骤是否正确,比如检查fromelf和objdump的参数是否正确,是否真的能生成反汇编文件。同时,是否需要先编译项目生成对应的elf或axf文件,再执行反汇编命令。 还要注意用户可能遇到的常见问题,比如环境变量没有配置导致找不到工具链,或者路径中有空格需要引号包裹等。可能需要给出不同操作系统下的示例,或者指出路径差异。 最后,总结几种常用方法,确保用户能根据自己使用的工具选择合适的方式。同时保持回答结构清晰,逐步引导用户操作,确保他们能顺利生成反汇编文件。</think>在STM32H750开发中生成反汇编文件可通过以下步骤实现,这里提供两种主流方法: 一、使用IDE内置功能(以Keil MDK为例) 1. 编译工程生成`.axf`或`.elf`文件 2. 打开工程选项 → Output选项卡 3. 勾选`Create HEX File`和`Browse Information` 4. 在User选项卡添加生成后执行命令: ``` fromelf --text -c -d --output=@L.lst !L ``` 这将生成`.lst`反汇编文件 二、使用GCC工具链(适用于STM32CubeIDE/VSCode) 1. 编译生成`.elf`文件 2. 执行命令(路径需根据实际安装位置调整): ```bash arm-none-eabi-objdump -D -S your_project.elf > disassembly.s ``` Windows示例: ``` "C:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2021.10\bin\arm-none-eabi-objdump.exe" -D -S build/your_project.elf > disassembly.s ``` 三、关键注意事项 1. 架构匹配:必须使用`arm-none-eabi`系列工具链 2. 调试信息:编译时需保留调试符号(-g选项) 3. 地址对应:反汇编中的地址与芯片内存映射直接对应 4. 交叉验证:可通过反汇编确认优化效果和代码体积 反汇编文件主要用途: - 分析编译器优化行为 - 调试HardFault等异常时定位问题地址 - 验证链接脚本正确性 - 逆向工程分析(需配合芯片参考手册) 附加技巧:在STM32CubeIDE中可右键工程 → Properties → C/C++ Build → Settings → Build Steps → Post-build steps添加自定义objdump命令实现自动生成。
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值