我需要知道使用mov指令直接加载代码段寄存器是否有任何限制。这让我在经历从真实的模式到保护模式的切换时感到震惊。我发现,为了在代码段中放入正确的值,“跳转”指令被用来设置正确的段。那么,这种跳转指令的使用是不是由于任何这样的限制?为什么我们不能直接把一个值加载到代码段中?
cwdobuhd1#
设置CS将是一个跳转,因为代码获取是从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不是,这一事实很奇怪。相关:是否可以在8086汇编中操作指令指针?What is the purpose of CS and IP registers in Intel 8086 assembly?请记住,386保护模式是一个扩展;在真实的模式下,CS value 直接用作段基址= cs<<4。加载具有相同基址的新描述符的用例是386的新用例。(实际上是286保护模式)。在此之前,mov cs, r/m16或pop cs操作码并没有真正的用例,因此英特尔将这些指令编码保留用于其他用途。这简化了未来的CPU,因为不必支持mov cs, r/m或pop cs作为跳转指令,这些指令必须丢弃预取的代码。(In 8086的某些早期版本X1 M14 N1 X确实存在,遵循与其它段寄存器的X1 M15 N1 X/X1 M16 N1 X相同的模式,并且它具有操作码X1 M17 N1 X,但Intel明智地决定保留0F,以便在未来的x86 CPU中用作多字节操作码的转义字节。(你会怎么做?))在保护模式下更改CS甚至比在真实的模式下更不常见(主流操作系统使用平面内存模型),因此完全没有必要开始支持mov到CS。jmp far工作得非常好,事实上更好,因为您不需要确保IP/EIP相对于段基的偏移在之前/之后相同。正如Margaret所指出的,CS选择器的低2位是286或386保护模式下的当前特权级别(就像在x86-64长模式下),所以通常只有当你想执行不同的代码,而不是继续执行下一个代码时,才会这样做。这种特殊情况通常只有在从真实的模式转换到保护模式时才会出现,您可能希望加载CS以进入32位模式,而根本不改变代码获取的来源。但是,更改CS本身将更新CS基址,因此即使允许mov cs, reg也不会使这变得更容易。
jmp far
call far
ret far
mov cs, ax
new_CS_base:old_IP+2
mov cs,ax
pop cs
pop ds
cs<<4
mov cs, r/m16
mov cs, r/m
0F
mov
IP
EIP
mov cs, reg
1条答案
按热度按时间cwdobuhd1#
设置CS将是一个跳转,因为代码获取是从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
不是,这一事实很奇怪。相关:是否可以在8086汇编中操作指令指针?
What is the purpose of CS and IP registers in Intel 8086 assembly?
请记住,386保护模式是一个扩展;在真实的模式下,CS value 直接用作段基址=
cs<<4
。加载具有相同基址的新描述符的用例是386的新用例。(实际上是286保护模式)。在此之前,mov cs, r/m16
或pop cs
操作码并没有真正的用例,因此英特尔将这些指令编码保留用于其他用途。这简化了未来的CPU,因为不必支持
mov cs, r/m
或pop cs
作为跳转指令,这些指令必须丢弃预取的代码。(In 8086的某些早期版本X1 M14 N1 X确实存在,遵循与其它段寄存器的X1 M15 N1 X/X1 M16 N1 X相同的模式,并且它具有操作码X1 M17 N1 X,但Intel明智地决定保留
0F
,以便在未来的x86 CPU中用作多字节操作码的转义字节。(你会怎么做?))在保护模式下更改CS甚至比在真实的模式下更不常见(主流操作系统使用平面内存模型),因此完全没有必要开始支持
mov
到CS。jmp far
工作得非常好,事实上更好,因为您不需要确保IP
/EIP
相对于段基的偏移在之前/之后相同。正如Margaret所指出的,CS选择器的低2位是286或386保护模式下的当前特权级别(就像在x86-64长模式下),所以通常只有当你想执行不同的代码,而不是继续执行下一个代码时,才会这样做。这种特殊情况通常只有在从真实的模式转换到保护模式时才会出现,您可能希望加载CS以进入32位模式,而根本不改变代码获取的来源。但是,更改CS本身将更新CS基址,因此即使允许
mov cs, reg
也不会使这变得更容易。