设置 CS 会be跳转,因为代码获取发生在 CS:IP(或 CS:RIP/EIP)。
这是有道理的,这样做仅限于jmp far
/ call far
/ ret far
和其他控制转移指令。
更改 CS 而不更改 IP 会很奇怪:假设的下一条指令之后执行mov cs, ax
指令将是new_CS_base:old_IP+2
(因为mov cs,ax
如果不使用操作数大小前缀,则长度为 2 个字节。)
当然,您可以进行设置,以便您的代码位于相对于两个不同段基的相同 IP 偏移量,但事实是pop cs
是一个跳跃pop ds
不是只是奇怪。强制您同时设置 CS 和 IPjmp
对我来说似乎很理智/正常。
有关的:是否可以在 8086 汇编中操作指令指针?.
Intel 8086汇编中CS和IP寄存器的用途是什么?
请记住,386 保护模式是一种扩展;在实模式下CSvalue直接用作段基 =cs<<4
. 加载具有相同基数的新描述符的用例是 386 中的新用例。(实际上是286保护模式)。在此之前,并没有真正的用例mov cs, r/m16
or pop cs
操作码,因此英特尔保留这些指令编码用于其他用途。
无需支持,从而简化了未来的 CPUmov cs, r/m
or pop cs
作为必须丢弃预取代码的跳转指令。
(在 8086 的一些早期版本中,pop cs
确实存在,遵循与push
/pop
其他段寄存器,并且它有操作码0x0f
,但英特尔明智地决定保留0F
用作未来 x86 CPU 中多字节操作码的转义字节。如果改变CS段寄存器会发生什么? (你会怎么做?)).
在保护模式下更改 CS 比在实模式下更不常见(主流操作系统使用平面内存模型),因此绝对没有必要开始支持mov
到CS。jmp far
工作得很好,而且事实上更好,因为你不需要确保IP
/ EIP
相对于段基址的偏移量前后相同。
正如 Margaret 指出的,CS 选择器的低 2 位是 286 或 386 保护模式(如 x86-64 长模式)中的当前权限级别,因此通常仅在您想要执行不同的代码而不是继续执行时才执行此操作不管接下来发生什么。这种特殊情况通常只在从实模式转换到保护模式期间出现,您可能希望加载 CS 以进入 32 位模式,而根本不改变代码获取的来源。但是改变 CS 本质上会更新 CS 基地址,所以即使允许mov cs, reg
不会让这变得更容易。