Ami*_*ugh 3 x86 assembly memory-segmentation
我需要知道是否有直接使用mov指令加载代码段寄存器的限制。
从实模式切换到保护模式时,这让我感到震惊。我发现为了在代码段中放入正确的值,“跳转”指令用于设置正确的段。
那么,由于任何这样的限制,跳转指令的这种用法吗?为什么我们不能直接将值加载到代码段中?
设置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对我来说似乎很理智/正常。
请记住,386保护模式是扩展。在实模式下,CS 值直接用作线段base = cs<<4。 加载具有相同基数的新描述符的用例是386(或286保护模式)的新增功能。在此之前,并没有真正的用例mov cs, r/m16或pop cs操作码用例,因此英特尔保留了这些指令编码供其他用途。
不必支持mov cs, r/m或pop cs作为必须丢弃预取代码的跳转指令,从而简化了将来的CPU 。
(在8086一些早期版本中,pop cs确实存在,遵循相同的模式push/ pop其他段的REG,并且它有操作码0x0f,但英特尔明智地决定储备0F用作未来的x86 CPU的多字节操作码的逃逸字节。 什么更改CS段寄存器会发生什么?)。
在保护模式下更改CS的情况甚至比在实模式下少得多,因此绝对不需要开始支持movCS。 jmp far可以很好地工作,并且实际上更好,因为您无需确保相对于段基的IP/ EIP偏移之前/之后相同。