最近,我意识到,作为他的8086逆向工程系列的一部分,肯·谢里夫(Ken Shirriff)在网上发布了一张8086芯片的高分辨率照片,上面去掉了金属层。这是我一段时间以来一直在寻找的东西,以便提取和反汇编8086微码。我之前发现了芯片的非常高分辨率的照片,金属层完好无损,但微码ROM只有一半的位是可读的。Ken还发布了一张8088微码ROM的高分辨率照片,这张照片非常相似,但并不完全相同。我非常好奇,想知道有什么不同。
我使用bitract从两个主微码ROM中提取位,也从转换ROM中提取位,转换ROM将操作码位模式映射到主微码ROM中的位置。
该微码在美国专利4363091中有部分记录。具体地说,该专利具有几个微码例程源代码列表。在这些指令中,有一些我能够在ROM转储中找到的指令部分的特定模式。这使我能够计算出ROM中的位模式如何与微码指令集的操作数和操作码相对应,其方式类似于破解单字母替换密码。我得到的微码ROM的反汇编可以在这里找到,我的反汇编程序的代码在GitHub上。
这次拆卸回答了我对8088和8086的许多问题。这篇文章的其余部分包含了这些问题的答案和我在微码中发现的其他有趣的东西。
不同之处在于中断处理代码。我认为归根结底是8086执行两次特殊的总线访问来确认中断(一次是告诉PIC它已准备好服务中断,第二次是获取需要服务的IRQ的中断号)。由于某些原因,这些都是字大小的访问,所以8088会将它们分成四个访问,而不是两个访问。这会使PIC感到困惑,因此8088改为执行单一访问,并依赖BIU将访问一分为二。其他变化似乎与此相关。
基本上都是。然而,也有不同之处(这增加了破译过程的一些复杂性)。不同之处在于字符串指令。例如,专利中的";STS&34;(STOSB/STOSW)指令是:
CR S D类型a b F-0 IK接口7 F1 11(M)OPR 6带DA,BL2接口IK 0 F1 03 4无RNI。
0 IK-&>IND 7 F1 RPTS1 M-&>OPR 6 w DA,BL2 Ind->;IK 0 NF1 53 Sigma->;tmpc 5 int RPTI4 tmpc->;BC 0新西兰15 4无RNI
箭头并没有什么不同-我只是把它放在反汇编中,以强调微码指令的Move部分中数据移动的方向。同样,专利列表中的";F11&34;与我的反汇编中的";F1rpts";相同-我用名称替换子例程编号以便于阅读。
专利中的版本在处理字符串的任何迭代之前,会检查例程中是否有挂起的中断。这意味着如果有一个连续的中断风暴,字符串指令将不会有任何进展。CPU中的版本会纠正这一点,并在完成存储后检查第3行上的中断,从而允许其继续进行。这可能不是在正常操作中预期会发生的情况(事实上,我似乎记得我的8088和8086机器崩溃的原因是中断发生得太快而无法得到服务)。所做的更改很可能是为了适应使用陷阱标志进行的调试(这实质上意味着在设置陷阱标志时总是有一个中断挂起)。如果没有此更改,使用重复字符串指令的代码不会在调试器下运行。
根据微码,8086有多少条不同的指令?他们是什么?。
MOV RM<;->;r 4 3LEA 1 1alu RM<;->;R 32 4ALU RM,I 4 5MOV RM,I 2 4ALU r,I 16 4 MOV r,I 16 3PUSH RW 8 4PUSH Sr 4 4PUSHF 1 4POP RW 8 3POP Sr 4 3POPF 1 3POP RMW 1 6CBW 1 2CWD 1 7MOV A,[I]2 4MOV[I],A 2 4CALL CD 1 4CALL CW 1 8XCHG AX,RW 8 3ROT。A 2 2RET 2 4RETF 2 2IRET 1 4RET/RETF iW 4 4JMP CW/JMP CB 2 6JMP CD 1 7Jcond 32 3MOV RMW<;->;Sr 2 2LES 1 4LDS 1 4WAIT 1 9(不连续)SAHF 1 4LAHF 1 2ESC 8 1XLAT 1 5STOS 2 6(不连续)CMPS/SCAS 4 13(不连续)MOVS/LODS 4 11(不连续)JCXZ 1 5(不连续)LOOPNE/Loope 2 5LOOP 1 4DAA/DAS 2 4aaa/AAS 2 8AAD 1 4AAM 1 6INC。
这些不连续的指令很可能被分解了,因为它们有错误修复,使得它们对于原始插槽来说太长了。同样,POP RMW&34;似乎缩短了至少3条指令,因为它后面有一个间隙。在编写代码之后四处移动代码(以及更新所有的远跳转/调用位置)可能会很棘手。
段覆盖前缀(CS:、SS:、DS:和ES:)没有微码。也不适用于其他前缀(REP、REPNE和LOCK),也不适用于指令CLC、STC、CLI、STI、CLD、STD、CMC和HLT。";组";操作码0xf6、0xf7、0xfe和0xff没有顶级微码指令。因此,操作码的高位字节中没有一条指令最初由微码处理。这些指令中的大多数都非常简单,并且可能更好地由随机逻辑来完成。HLT有点令人惊讶--我真的以为我会为它找到一个微码循环,因为它似乎每隔一个周期才检查一次中断。
组指令的解码略有不同,但处理它们的微码例程分解如下:
INC/DEC RM 3PUSH RM 4NOT RM 3NEG RM 3CALL Far RM 8CALL RM 8TEST RM,I 4JMP RM 2JMP Far RM 4IMUL/MUL人民币8IMUL/MUL RMW 8IDIV/DIV人民币8IDIV/DIV RMW 8