与8086相比,8080的指令集在指令长度方面非常简单。只有三种情况:
- 1 字节指令:例如,
XRA A。
- 1 字节指令后跟 1 字节数据:例如,
MVI A,0。
- 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 拆卸的部分乐趣在于发现这些技巧!