汇编和反汇编的理解

汇编语言是高级语言转换成机器码的桥梁,通过汇编语言的编译转换成机器码,计算机就可以执行程序。因为在计算机中,所有的程序都是按照机器码执行的,所以对汇编语言的理解,能够增加对底层执行的认识。

下面介绍的是汇编语言编译的过程(手工的方式编译68HC11的子例程):

LDAA(立即寻址)指令的长度为两个字节,操作码是86(这个是在计算机中的机器码,也就是说如果计算机存储的数据是86,就会执行LDAA操作),另一个字节是操作码。而ADDA(立即寻址)指令的长度也是两个字节。操作码是8B,在技术手册或程序员参考手册中查找其余的操作码,就对得到如下的结果:

0100    86    10    LDAA #$10    ;把第一个数载入到累加器A中
0102    8B    1F    ADDA #$1F    ;把第二个数加到累加器A
0104    8B    0C    ADDA #$0C    ;把第三个数加到累加器A
0106    B7    00 27 STAA $0027   ;把累加器A的内容存到地址0x0027中
0109    39    RTS                ;返回主程序

此处,做了如下的假定:程序的起始地址是0x0100,每条指令的地址都附在左左边。注意地址的变化与指令长度的关系。

如果我们要明确的告诉编译器,程序的起始地址是0x0100,则可以使用org这条伪指令语句:

org 0x0100

org伪指令必须始终放在第一条指令的前面,用于把程序的代码定位在特定的位置上。例如处理器芯片的ROM上。

 

反汇编

反汇编就是我们把一系列的机器码转换成改程序的助记符。如果我们拿到一份机器码程序,而我们想要知道他的功能和工作方式,可以对机器码进行反汇编。

例如,我们拿到了一份68HC11机器码程序的字节序如下:

8E 56 78 86 56 84 06 36 4C 36

首先,我们假定第一个字节为操作码,在Motorola (或68HC11)指令集的数据手册里,查找0x8E这个操作码,就会发现它是LDS(load stack pointer 加载堆载指针)指令,而该指令的长度为3个字节(一个为操作码,另外两个为操作数)。因此,如果第一个字节为操作码,则其后的两个字节为相关的数据。所以,第一条指令就是:

8E 56 78    LDS #$5678;    把0x5678载入到堆栈指针中

后面的指令操作首先要查找到机器码对应的操作码,再看这个操作码有几个字节,然后就能够反汇编出机器码的程序。

转载自:《嵌入式硬件设计第2版》53-56

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页