汇编与反汇编

程序处理的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使用

相关推荐
我在人间贩卖青春4 天前
汇编之伪指令
汇编·伪指令
我在人间贩卖青春4 天前
汇编之伪操作
汇编·伪操作
济6174 天前
FreeRTOS基础--堆栈概念与汇编指令实战解析
汇编·嵌入式·freertos
myloveasuka4 天前
汇编TEST指令
汇编
我在人间贩卖青春4 天前
汇编编程驱动LED
汇编·点亮led
我在人间贩卖青春5 天前
汇编和C编程相互调用
汇编·混合编程
myloveasuka5 天前
寻址方式笔记
汇编·笔记·计算机组成原理
请输入蚊子5 天前
《操作系统真象还原》 第六章 完善内核
linux·汇编·操作系统·bochs·操作系统真像还原
myloveasuka5 天前
指令格式举例
汇编·笔记·计算机组成原理
我在人间贩卖青春6 天前
汇编之分支跳转指令
汇编·arm·分支跳转