跟我一起学RT-Thread之反汇编

1. 程序处理的4个步骤

我们现在给出两个文件start.S、main.c,它们的处理过程如下:

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

生成elf文件所需要的四大步骤为:

预处理 -> 编译 -> 汇编 -> 链接

补充:

ELF 全称 “Executable and Linkable Format”,即可执行可链接文件格式,目前常见的Linux、 Android可执行文件、共享库(.so)、目标文件( .o)以及Core 文件(吐核)均为此格式。

我们需要理解“汇编”、“反汇编”的概念:

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

2. Keil下怎么反汇编

2.1. 准备工具

Jlink或者STlink

2.2. 进行反汇编

2.2.1.打开keil软件

先对工程进行编译,然后进入调试界面。

2.2.2.进入调试界面

进入调试界面后,按上述步骤进行,显示出反汇编界面。

2.2.3.进入反汇编界面

红色箭头所指向的区域就是反汇编界面,这是我们深入ARM架构的必经之路。

3. Gcc下反汇编

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

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

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

4. 机器码与汇编

参考资料:

ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf P410

前面介绍过伪指令,伪指令是实际不存在的ARM命令,编译器在编译时转换成存在的ARM指令。

LDR SP, =(0x20000000+0x10000)   // STM32F103
ldr sp, =(0x80000000+0x100000)  // IMX6ULL
ldr sp, =0xc0000000 + 0x100000  // STM32MP157 A7

我们可以通过反汇编来查看, 只摘取前面一小段。

4.1 STM32F103反汇编

我们只摘取前面一小段,第一列是地址,第二列是机器码,第三列是汇编:

在这里插入图片描述

4.2 STM32MP157反汇编

在这里插入图片描述

4.3 IMX6ULL反汇编

在这里插入图片描述

4.4 机器码与汇编示例

4.4.1 Thumb/Thumb2指令集

4.4.2 ARM指令集

4.5 解析LDR伪指令

为什么 PC=当前指令+4或8?

  • CORTEX M3/M4
    使用Thumb2指令集,一条指令是16位或32位。

  • CORTEX A7

    默认使用ARM指令集,一条指令是32位的。不支持thumb2指令集。

    ARM指令采用流水线机制:

    • 当前执行地址A的指令,

    • 同时已经在对下一条指令进行译码

    • 同时已经在读取下下一条指令:PC = A +4 (Thumb/Thumb2指令集)、PC = A + 8 (ARM指令集)

      解释:Thumb2指令集支持16位和32位指令混编,那为什么 PC=当前指令+4?自我猜测是为了简化运算而选择的

4.6 总结

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

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

    最终要转换为机器码。

  • 机器码给CPU使用

  • 汇编语言的本质就是机器码,在进行汇编的时候会转换成机器码,同样的汇编程序可以转换成不同的机器码取决于编译器(在不同的架构下,有着不同的指令集)。

  • 在不同架构下,指令集不同。但是我们并不需要去关心指令集的问题,编译器会将汇编程序转换为机器码,也可以将机器码转换为汇编程序。我们只需要关心汇编程序即可,不论什么架构(ARM),汇编语句都是通用的!!!

猜你喜欢

转载自blog.csdn.net/qq_46359697/article/details/113471074