-5

我正在为 8080 组装制作反汇编程序。如果我错了,请纠正我:我所要做的就是逐字节读取二进制文件,将每个字节翻译成一个命令。或者是否存在会增加命令长度的条件(在二进制中)。

4

2 回答 2

4

为什么你有一个dos标签?你的意思是8088而不是8080?

在任何一种情况下都不,绝对不是你不能一次只线性地去一个字节。这两个指令集都是可变长度指令。您必须查看它们如何引导、向量表或入口地址,然后您必须遵循可能的执行路径。

从重置入口点开始线性反汇编,直到到达有条件或无条件的分支,这为您提供了另外两个线性反汇编的入口点。一个无条件分支结束一个部分的反汇编。

您应该跟踪哪些字节是操作码,哪些字节是这些操作码的附加数据。如果你有字节 ijklm 和 i,k 和 l 是操作码,或者说指令的第一个字节,而 j 和 m 是辅助字节。然后,如果您在其他地方找到指向 k 字节所在地址的分支,那没关系,但如果您找到指向 j 所在字节的分支,要么是聪明的黑客,要么你有问题。如果该问题是故意防止拆卸,也不会不时感到惊讶。编译器生成的代码通常不会有这个问题,但手工汇编(机器代码)可能(对于意外情况)并且越往后走,您越有可能遇到手工编码的汇编/机器代码。

于 2016-05-14T13:46:30.010 回答
2

与8086相比,8080的指令集在指令长度方面非常简单。只有三种情况:

  1. 1 字节指令:例如,XRA A.
  2. 1 字节指令后跟 1 字节数据:例如,MVI A,0.
  3. 1 字节指令后跟 2 字节数据:例如,LXI B,0.

这使得反汇编器非常容易。事实上,我通常是这样学习 8080 汇编语言的:通过反汇编计算机上的内置 Basic 解释器(使用带有大量 PEEK 命令的 Basic 编写的反汇编器)并使用知识构建 BIOS 以便能够安装 CP/M。

dwelch 是正确的,代码可以跳转到指令的中间。Microsoft Basic 解释器正是使用了这个技巧,如下所示:

01 2E 00
01 2E 01
01 2E 02
... code using the value of L

在此序列中调用字节偏移量 01 将执行2E 00,即将MVI L,0寄存器 L 设置为零。然后是两条LXI B指令,将寄存器 BC 设置为 012E 和 022E,这是没有意义的(并且该值被忽略)。

在此序列中调用字节偏移量 04 将执行2E 01,即MVI L,1,它将寄存器 L 设置为 1。然后是一条LXI B指令,将寄存器 BC 设置为 022E,这是没有意义的(并且该值被忽略)。

在此序列中调用字节偏移量 07 将执行2E 02,即将MVI L,2寄存器 L 设置为 2。

底线是,在偏移量 09 处,如果调用了偏移量 01,我们最终得到 L=0,如果调用了偏移量 04,我们最终得到 L=1,或者如果调用了偏移量 07,我们最终得到 L=2。每个调用只占用 3 个字节(CD xxx xx),设置这些不同的 L 值的开销只有 9 个字节。

如果没有这种聪明,要么必须使用 15 个字节来设置 L(2 个字节)并跳转到使用 L(3 个字节)的任何例程的开头,要么必须由调用者设置 L ,这意味着对例程的每次调用将占用 5 个字节(2 个用于设置 L,3 个用于进行调用)而不是 3 个。

8080 拆卸的部分乐趣在于发现这些技巧!

于 2016-05-31T14:58:36.963 回答