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

Ami*_*ugh 3 x86 assembly memory-segmentation

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

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

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

Pet*_*des 5

设置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不是奇怪的事实。强迫您同时设置CS和IP,这jmp对我来说似乎很理智/正常。

相关:在8086汇编中可以操纵指令指针吗?


请记住,386保护模式是扩展。在实模式下,CS 直接用作线段base = cs<<4加载具有相同基数的新描述符的用例是386(或286保护模式)的新增功能。在此之前,并没有真正的用例mov cs, r/m16pop cs操作码用例,因此英特尔保留了这些指令编码供其他用途。

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

(在8086一些早期版本中,pop cs确实存在,遵循相同的模式push/ pop其他段的REG,并且它有操作码0x0f,但英特尔明智地决定储备0F用作未来的x86 CPU的多字节操作码的逃逸字节。 什么更改CS段寄存器会发生什么?)。


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

  • 使 `mov cs, reg` 在 286+ 中完全无效的一件事是 `cs` 在 PM 中包含 CPL。 (2认同)