为什么即使可以设置其他代码,也不能mov设置代码段寄存器CS?

时间:2018-09-25 04:07:42

标签: assembly x86 memory-segmentation

我需要知道是否有直接使用mov指令加载代码段寄存器的限制。

在经历从实模式到保护模式的切换时,这让我感到震惊。我发现为了在代码段中放入正确的值,“跳转”指令用于设置正确的段。

那么由于任何这样的限制,跳转指令的这种用法吗?为什么我们不能直接将值加载到代码段中?

1 个答案:

答案 0 :(得分:4)

设置CS会 ,因为代码提取是通过CS:IP(或CS:RIP / EIP)进行的。

这样做仅限于jmp far / call far / ret far和其他控制转移指令。

在不更改IP的情况下更改CS会很奇怪:在假设的mov cs, ax指令之后要执行的下一条指令将是new_CS_base:old_IP+2(因为如果您不使用mov cs,ax,则长度为2个字节操作数大小的前缀。)

当然,您可以进行设置,以便相对于两个不同的段基础,代码具有相同的IP偏移,但是pop cs是跳跃式的,而pop ds不是跳跃式的事实。强迫您使用jmp同时设置CS和IP对我来说似乎很理智/正常。

相关:Is it possible to manipulate the instruction pointer in 8086 assembly?


请记住,386保护模式是扩展。在实模式下,CS value 直接用作段基= cs<<4用相同的基数加载新描述符的用例是386的新用法(或者可能是286保护模式。在此之前,mov cs, r/m16pop cs操作码,因此Intel保留了这些指令编码供其他用途。

不必将mov cs, r/mpop cs作为必须丢弃预取代码的跳转指令来支持,从而简化了将来的CPU。

(在8086的某些早期版本中,确实存在pop cs,遵循与其他网段reg的push / pop相同的模式,并且其操作码为0x0f,但是Intel明智地决定保留0F以便在将来的x86 CPU中用作多字节操作码的转义字节。What would happen if the CS segment register is changed?)。


在保护模式下更改CS的情况比在实模式下更为罕见,因此,绝对不需要开始支持mov到CS。 jmp far可以很好地工作,并且实际上更好,因为您无需确保相对于段基的IP / EIP偏移前后是相同的。