5

主要是历史兴趣,如果我要为汇编程序实现 8086 兼容性,哪些操作数被认为对ESC指令有效?

ESC opcode, source

从 8086 Programmer's manual 我知道,这opcode是 0 到 63 范围内的立即数,source是寄存器或内存。但是可以对哪些寄存器进行编码?两者兼有reg8reg16reg16?如果source是内存,操作数大小(mem8mem16)重要吗?

基本上,从指令编码的角度来看,上述两者都无关紧要(例如,两者esc 0x01, ch都会esc 0x01, bp产生相同的结果),但也许汇编程序有强制限制

最后,我在哪里可以找到ESC操作码的描述?

4

1 回答 1

12

8086 有一个共同指定的操作码空间ESC(逃逸到协处理器)。它占据范围d8df。该指令空间中的每条指令后跟一个 modr/m 字节,并且根据 mod 字段,零到两个位移字节。当 8086 遇到ESC带有两个寄存器操作数的指令时(即 mod = 11),它会执行 nop。当处理器遇到ESC带有内存操作数的指令时,从内存操作数所指示的地址开始执行一个读周期,结果被丢弃。

使用两条特殊的信号线,协处理器可以区分数据取指和指令取指,允许它与 8086 并行解码指令流。

8087 使用这种机制来挂钩指令流:操作码字节中的三个可用位与 modr/m 字节中 reg 字段的三个位一起形成一个六位操作码。modr/m 字节的 r/m 字段用于指定 FPU 寄存器堆栈上的位置(如果 mod = 11,表示两个寄存器操作数)或内存操作数。一些操作码根据 r/m 字段的内容对各种指令进行编码。在所有这些情况下,一条指令针对内存操作数进行编码,而另外八条指令针对每个可能的寄存器操作数进行编码。

当 8086 在获取指令后立即执行虚拟获取时,8087 会注册并记住地址。对于从内存加载的指令,它会加载内存操作数的附加字并执行其功能。在存储的情况下,它会忽略获取的结果并将其值存储到 8086 指示的地址。

8087 与 8086 异步执行操作。但是,不存在隐式同步。如果在协处理器忙时尝试发出ESC指令,则该指令将被静默忽略。为了解决这个问题,8087 在执行操作时将其BUSY引脚(连接到 8086 的TEST引脚)置位。程序员可以发出wait指令(9b, 等待协处理器准备好)等到 8087 完成操作并随后释放该WAIT行。这通常在每条 8087 指令之前完成,当时的许多汇编程序会自动插入WAIT前缀。对于高性能代码,也很常见的是手动计算 8087 执行某条指令需要多长时间,并省略上一条wait浮点指令保证完成的时间。

于 2017-03-01T23:33:12.730 回答