为什么即使可以设置其他代码,也不能mov设置代码段寄存器CS? [英] Why can't mov set CS, the code segment register, even though it can set others?

查看:253
本文介绍了为什么即使可以设置其他代码,也不能mov设置代码段寄存器CS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I needed to know if there is any restriction on loading code segment registers directly by using mov instructions .

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

This struck me while going through the switching from real mode to protected mode . I found that in order to put the correct value in the code segment "jump" instruction is used to set the correct segment .

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

So is this usage of jump instruction owing to any such restriction ? Why cannot we directly load a value into the code segment ?

推荐答案

设置CS可能会 ,因为代码提取是通过CS:IP(或CS:RIP/EIP)进行的.

Setting CS would be a jump, because code-fetch happens from CS:IP (or CS:RIP/EIP).

这样做仅限于jmp far/call far/ret far和其他控制转移指令.

It makes sense that doing this is restricted to jmp far / call far / ret far and other control-transfer instructions.

在不更改IP的情况下更改CS会很奇怪:在假设的mov cs, ax指令之后执行的下一条指令将是new_CS_base:old_IP+2(因为如果不使用操作数大小的前缀,mov cs,ax的长度为2个字节). )

Changing CS without changing IP would be weird: the next instruction to execute after a hypothetical mov cs, ax instruction would be new_CS_base:old_IP+2 (because mov cs,ax is 2 bytes long if you don't use an operand-size prefix.)

当然,您可以进行设置,以便相对于两个不同的段基础,代码具有相同的IP偏移,但是pop cs是一个跳跃而pop ds不是一个事实,这很奇怪.强迫您使用jmp同时设置CS和IP对我来说似乎很理智/正常.

Sure you could set things up so you had code at the same IP offset relative to two different segment bases, but the fact that pop cs is a jump while pop ds isn't is just weird. Forcing you to set both CS and IP at the same time with a jmp seems pretty sane/normal to me.

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

请记住,386保护模式是扩展.在实模式下,CS 直接用作段基= cs<<4. 加载具有相同基数的新描述符的用例是386的新用法(或者可能是286保护模式.在此之前,mov cs, r/m16操作码,因此Intel保留了这些指令编码供其他用途.

Remember that 386 protected mode was an extension; in real mode the CS value was used directly as segment base = cs<<4. The use-case of loading a new descriptor with the same base was new with 386, (or maybe 286 protected mode. Before that there wasn't really a use-case for mov cs, r/m16 or pop cs opcodes, so Intel reserved those instruction encodings for other uses.

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

And simplified future CPUs by not having to support mov cs, r/m or pop cs as jump instructions that would have to discard prefetched code.

(在某些8086的早期版本中,确实存在pop cs,遵循与其他段regs的push/pop相同的模式,并且具有操作码0x0f,但是英特尔明智地决定保留用作将来的x86 CPU中多字节操作码的转义字节

(In some early versions of 8086, pop cs did exist, following the same pattern as push/pop of other segment regs, and it had opcode 0x0f, but Intel wisely decided to reserve 0F for use as an escape byte for multi-byte opcodes in future x86 CPUs. What would happen if the CS segment register is changed?).

在保护模式下更改CS的情况比在实模式下更为罕见,因此绝对不需要开始支持CS的mov. jmp far可以很好地工作,并且实际上更好,因为您不需要确保相对于段基的IP/EIP偏移前后都是相同的.

Changing CS in protected mode is even less common than in real mode, so there was definitely no need to start supporting mov to CS. jmp far works perfectly well, and better in fact because you don't need to ensure that the IP / EIP offset relative to the segment base is the same before/after.

这篇关于为什么即使可以设置其他代码,也不能mov设置代码段寄存器CS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆