什么是 8086 ESC 指令操作码
What are 8086 ESC instruction opcodes
主要是出于历史兴趣,如果我要为汇编程序实现 8086 兼容性,哪些操作数被认为对 ESC
指令有效?
ESC opcode, source
从 8086 程序员手册我知道,opcode
是 0 到 63 范围内的立即数,source
是寄存器或内存。但是可以对哪些寄存器进行编码呢? reg8
和 reg16
还是只有 reg16
?如果 source
是内存,操作数大小(mem8
或 mem16
)重要吗?
基本上,从指令编码的角度来看,以上两者并不重要(例如,esc 0x01, ch
和 esc 0x01, bp
都会产生相同的结果),但也许汇编器强制限制
最后但并非最不重要的一点是,我在哪里可以找到 ESC
操作码的描述?
8086有一个操作码space统称为ESC
(转义到协处理器)。它占据 d8
到 df
的范围。该指令中的每条指令 space 后跟一个 modr/m 字节,并且根据 mod 字段,零到两个位移字节。当 8086 遇到带有两个寄存器操作数的 ESC
指令时(即 mod = 11),它会执行 nop。当处理器遇到带有内存操作数的 ESC
指令时,从内存操作数指示的地址开始执行读取周期,并丢弃结果。
使用两条特殊信号线,协处理器可以区分数据提取和指令提取,从而允许它与 8086 并行解码指令流。
8087 使用此机制挂钩指令流:操作码字节中的三个可用位与 modr/m 字节中注册字段的三个位一起形成一个六位操作码。 modr/m 字节的 r/m 字段用于指定 FPU 寄存器堆栈上的位置(如果 mod = 11,表示两个寄存器操作数)或内存操作数。一些操作码根据 r/m 字段的内容编码各种指令。在所有这些情况下,一条指令针对内存操作数进行编码,而其他八条指令针对每个可能的寄存器操作数进行编码。
8087在8086取指令后立即执行伪取指令并记住地址时进行注册。如果是从内存加载的指令,它会加载内存操作数的附加字并执行其功能。在存储的情况下,它忽略获取的结果并将其值存储到 8086 指示的地址。
8087 与 8086 异步执行操作。但是,不存在隐式同步。如果在协处理器忙时尝试发出 ESC
指令,则该指令将被静默忽略。为了解决这个问题,8087 在执行操作时断言其 BUSY
引脚(连接到 8086 的 TEST
引脚)。程序员可以发出 wait
指令(9b
,等待协处理器就绪)等到 8087 结束操作并随后释放 WAIT
行。这通常在每条 8087 指令之前完成,并且当时的许多汇编器会自动插入 WAIT
前缀。对于高性能代码,通常是手动计算 8087 执行某条指令需要多长时间,并在保证前一个浮点指令完成时省略 wait
。
主要是出于历史兴趣,如果我要为汇编程序实现 8086 兼容性,哪些操作数被认为对 ESC
指令有效?
ESC opcode, source
从 8086 程序员手册我知道,opcode
是 0 到 63 范围内的立即数,source
是寄存器或内存。但是可以对哪些寄存器进行编码呢? reg8
和 reg16
还是只有 reg16
?如果 source
是内存,操作数大小(mem8
或 mem16
)重要吗?
基本上,从指令编码的角度来看,以上两者并不重要(例如,esc 0x01, ch
和 esc 0x01, bp
都会产生相同的结果),但也许汇编器强制限制
最后但并非最不重要的一点是,我在哪里可以找到 ESC
操作码的描述?
8086有一个操作码space统称为ESC
(转义到协处理器)。它占据 d8
到 df
的范围。该指令中的每条指令 space 后跟一个 modr/m 字节,并且根据 mod 字段,零到两个位移字节。当 8086 遇到带有两个寄存器操作数的 ESC
指令时(即 mod = 11),它会执行 nop。当处理器遇到带有内存操作数的 ESC
指令时,从内存操作数指示的地址开始执行读取周期,并丢弃结果。
使用两条特殊信号线,协处理器可以区分数据提取和指令提取,从而允许它与 8086 并行解码指令流。
8087 使用此机制挂钩指令流:操作码字节中的三个可用位与 modr/m 字节中注册字段的三个位一起形成一个六位操作码。 modr/m 字节的 r/m 字段用于指定 FPU 寄存器堆栈上的位置(如果 mod = 11,表示两个寄存器操作数)或内存操作数。一些操作码根据 r/m 字段的内容编码各种指令。在所有这些情况下,一条指令针对内存操作数进行编码,而其他八条指令针对每个可能的寄存器操作数进行编码。
8087在8086取指令后立即执行伪取指令并记住地址时进行注册。如果是从内存加载的指令,它会加载内存操作数的附加字并执行其功能。在存储的情况下,它忽略获取的结果并将其值存储到 8086 指示的地址。
8087 与 8086 异步执行操作。但是,不存在隐式同步。如果在协处理器忙时尝试发出 ESC
指令,则该指令将被静默忽略。为了解决这个问题,8087 在执行操作时断言其 BUSY
引脚(连接到 8086 的 TEST
引脚)。程序员可以发出 wait
指令(9b
,等待协处理器就绪)等到 8087 结束操作并随后释放 WAIT
行。这通常在每条 8087 指令之前完成,并且当时的许多汇编器会自动插入 WAIT
前缀。对于高性能代码,通常是手动计算 8087 执行某条指令需要多长时间,并在保证前一个浮点指令完成时省略 wait
。