我需要知道是否有直接使用mov指令加载代码段寄存器的限制。
在经历从实模式到保护模式的切换时,这让我感到震惊。我发现为了在代码段中放入正确的值,“跳转”指令用于设置正确的段。
那么由于任何这样的限制,跳转指令的这种用法吗?为什么我们不能直接将值加载到代码段中?
答案 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/m16
或pop cs
操作码,因此Intel保留了这些指令编码供其他用途。
不必将mov cs, r/m
或pop 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
偏移前后是相同的。