汇编与反汇编

程序处理的4个步骤

我们的第一个LED程序涉及两个文件:start.S、main.c,它们的处理过程如下:
在这里插入图片描述

  1. 对于汇编程序,经过汇编之后,转换成目标文件(里面包含机器码)。
  2. 对于C程序,经过预处理之后,得到.i文件,在经过编译后得到汇编文件,汇编文件经过汇编后得到目标文件。
  3. 所有目标文件经过链接之后,生成elf文件(可执行文件),再经过反汇编,得到汇编文件。

我们想深入理解ARM架构,深入理解汇编与C,想深入理解栈的作用,想深入理解C语言的实质,就必须把最终的可执行程序,反汇编后,得到汇编代码。

汇编与反汇编

  • 汇编:汇编文件转换成目标文件(里面是机器码)。
  • 反汇编:可执行文件(目标文件,里面是机器码),转换成汇编文件。

在这里插入图片描述

hex文件、bin文件、axf文件的区别

STM32也是用C语言来开发,也会经过类似的编译过程,只不过我们常常用MDK或者其它IDE来编译,其编译过程如下:
在这里插入图片描述
C文件经过armcc编译器形成目标文件,目标文件再与其他目标文件经过armlink链接器生成映像文件。
汇编代码经过armsm编译器生成目标文件,目标文件目标文件再与其他目标文件经过armlink链接器生成映像文件。

映像文件.axf再经过fromelf格式转换器生成二进制文件、十六进制文件。

在这里插入图片描述
在IDE中进行编译时,我们只需要点击编译按钮即可完成这些过程,编译过程用到的工具(.exe文件)在IDE的安装目录下,比如常用的MDK编译工具路径为:
在这里插入图片描述
在这里插入图片描述
一般这些IDE或者工具集的一些编译工具都放在bin文件夹里。比如MinGW工具集(里面包含gcc/g++编译器,可以编译在电脑上运行的程序)的编译工具所在路径:
在这里插入图片描述
我们的MDK编译时就是使用安装路径下的这些编译工具来完成我们的编译过程。
究其本质,我们在cmd命令窗口也是可以通过命令来编译我们的STM32程序的(前提是配好环境变量,否则得到编译工具所在的路径下进行编译)。
在这里插入图片描述
在cmd窗口下运行armcc命令,会发生什么?
在这里插入图片描述
有些常用的编译选项已经集成在MDK里供我们选择,比如:
在这里插入图片描述
可烧录文件
.axf文件、hex文件与bin文件都是可以运行在我们stm32上的,它们都存储了编译器根据源代码生成的机器码,根据应用场合的不同,它们又有所区别。

.axf:包含调试信息
.hex文件:包含地址信息
.bin文件:直接的代码映像

axf文件是编译器默认生成的文件,不仅包含代码数据,还包含着调试信息,在MDK里debug进行调试用的就是这个文件。

.hex文件在MDK里要勾选才可以生成:
在这里插入图片描述
hex文件是一种使用十六进制符号表示的代码记录,记录了代码应该存储到FLASH的哪个地址,下载器可以根据这些信息辅助下载。

bin文件是根据axf文件生成的,需要在MDK下添加类似如下格式命令来生成对应的.bin文件:
在这里插入图片描述
bin文件就是最小的可以运行的文件了,其包含最直接的代码映像。
这三个文件中axf文件最大,hex文件次之,bin文件最小,如:
在这里插入图片描述

KEIL下怎么反汇编

在KEIL的Uer选项中,添加这两项:

fromelf --bin --output=led.bin Objects\led_c.axf
fromelf --text -a -d --output=led.dis Objects\led_c.axf

然后重新编译,即可得到二进制文件led.bin,反汇编文件led.dis。
在这里插入图片描述

GCC反汇编

使用GCC工具链编译程序时,Makefile中有一句:

PREFIX = arm-linux-gnueabihf-
OBJDUMP =$(PREFIX)objdump
$(OBJDUMP) -D -m arm led.elf > led.dis

它就是把可执行程序led.elf反汇编,得到led.dis。

在这里插入图片描述
链接地址 机器码 汇编码
当前PC的值为下一条指令的地址0x0800008C
LDR SR,[PC,#4]
PC再偏移4个字节的地址0x08000090
在这里插入图片描述
把这个地址上的值2000c000存入SP寄存器。

机器码与汇编

伪指令是实际不存在的ARM指令,编译器在编译时转换成存在的ARM指令。
我们代码中的LDR SP, =(0X20000000+0XC000)这条伪指令的真实指令是什么呢?

STM32F103反汇编
在这里插入图片描述

  1. 链接地址
  2. 机器码或数值
  3. 汇编指令或数值

机器码与汇编示例

在这里插入图片描述

解析LDR伪指令

为什么PC=下一条指令+4或者+8呢?

  • CORTEX M3/M4:使用Thumb2指令集,一条指令是16位或32位
  • CORTEX A7:默认使用ARM指令集,一条指令是32位的。
  • ARM指令采用流水线机制:当前执行地址A的指令,同时已经对下一条指令进行译码,同时已经在读取下下条指令:PC=A+4(Thumb/Thumb2),PC=A+8(ARM指令集)

4.5 总结

  • C
    为了方便人类方便使用,发明的高级语言,要转换为汇编。

  • 汇编
    为了解放人类的记忆,发明的“助记符”,不用去记各类机器码。

    最终要转换为机器码。

  • 机器码

    给CPU使用

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

饼干饼干圆又圆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值