Skip to main content

为什么在8086处理器不能直接把立即数存入段寄存器

·173 words·1 min
海鱼Harry
Author
海鱼Harry
知我罪我

向段寄存器存内容的常见两步
#

如果有一个段地址,需要存入段寄存器(ES),在 8086 处理器中,通常要这样做:

mov ax, 0xb800;显存地址
mov es, ax

不能直接向 ES 直接传入立即数,必须先存入通用寄存器(如 ax),再从 ax 存入 ES。 根据 Quora 上 Paul 的回答,8086 确实是没有设计这样的指令:

The designers of the 8086 architecture didn’t consider being able to store an immediate into any segment register important enough to encode it as an instruction in the binary format. As such, you need to do this in two steps: load the immediate into ax and then store it into the segment register.

译: 8086 架构的设计者没有考虑能够将立即数存储到任何重要的段寄存器中,以将其编码为二进制格式的指令。因此,您需要分两步执行此操作:将立即数加载到 ax 中,然后将其存储到段寄存器中。

两种可能:

8086 时代不允许这复杂的设计了:

北极在知乎上的回答

我个人觉得,就是编码太麻烦,opcode不太够用,指令太长。 ……

8086寄存器编码.jpg
因为MOV操作的寄存器有两个,其中的一个还可能是内存,还可能是寄存器组合,这样的话,2*3bit(注:原文应指8bit)用于描述寄存器,剩下2个bit用于描述是内存还是别的东西,这样算下来,一个字节勉强够用。而如果把段寄存器加上,就需要4个bit编码一个寄存器,仅仅描述两个寄存器就需要一个字节,加上其它的修饰,MOV指令长度就需要整体增加一个字节,这对于过去的计算机来说,开销无疑是非常巨大的,过去计算机内存都是以KB计算的,每个MOV指令增加一个字节,在设计者看来是无法接受的。

这大概就是在说,为了节省节省开销,没有更多空间留给 mov es imd 形式的指令设计了。 这与 Paul 的回答中的评论是一致的:

I don’t think it’s impossible to fit it in, but rather omitting it simplifies the processor design, and those times are different from today in which you add extra complexity for performance. 译:我不认为不可能设计并适配它(指mov es imd 形式的指令),而是省略它可以简化处理器的设计,而那个时代与今天这为了性能而增加额外的复杂性的时代不同。

安全性问题:

CSDN 上有一个很老的帖子,其中有一个回复考虑到了安全性的问题:

burningstyle的回复.jpg

burningstyle的回复.jpg 在 Paul 的回答中也有提到:

Now storing an immediate into a segment register has a second issue — if you’re not the OS, how do you know that that memory region doesn’t belong to someone else? 译:现在,将一个即时数据存储到段寄存器中还有一个问题–如果你不是操作系统,你怎么知道那个内存区域不属于其他人?

其实这个不难理解,汇编程序对内存的使用应当存在一定的抽象以保证安全。