为什么mov指令使用ax而不是直接使用两个段寄存器?
我看到这样的代码:
mov ax, cs
mov ds, ax
mov es, ax
为什么我不能将其压缩为:
mov ds, cs
mov es, cs
由于使用累加器寄存器,第一种方法是否更快? 但这看起来并不直观,因为 cs 和 ds 是段寄存器。 还是有一些我不知道的限制?
顺便说一句,我正在使用 nasm。
I see code like:
mov ax, cs
mov ds, ax
mov es, ax
Why can't I just compress this to:
mov ds, cs
mov es, cs
Is the first way faster since its using the accumulator register? But that wouldn't seem intuitive since cs and ds are segment registers. Or is there some restriction that I'm unaware of?
I'm using nasm by the way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你不能将段寄存器移动到段寄存器——没有相关的指令。
You can't mov segment register to segment register -- there's no instruction for it.
处理器中只有这么多空间来容纳微代码及其所有指令。 因此,对于很少使用的操作湖更改段寄存器来说,一条通用指令通常比几条专用指令更受青睐。 此外,对于某些处理器来说,指令数量绝对受到架构的限制 - 例如,最初的 8080 处理器仅限于 256 条指令,因为它们都必须将操作码编码在单个字节中。
There is only so much room in a processor for the microcode for all its instructions. So one general instruction is often preferred over several special purpose ones for rarely uused operations lake changing segment registers. Also, for some processors the number of instructions is absolutely limited by the architecture - for example, the original 8080 processor was limited to 256 instructions as they all had to have the op code encoded in a single byte.
查看 英特尔手册第 2 卷指令集参考 - 325383-056US 2015 年 9 月“MOV 移动”专栏“操作说明”。
寄存器的唯一 16 位 mov 编码为:
并且“3.1.1.3 操作码汇总表中的指令列”解释:
属性为16位。 字通用寄存器有:AX、CX、DX、BX、SP、BP、SI、DI。
因此,
mov ds, cs
不可编码,因为没有mov Sreg, Sreg
版本。Look at the Intel Manual Volume 2 Instruction Set Reference - 325383-056US September 2015 "MOV Move" column "Instruction".
The only 16-bit mov to registers is encoded in:
And "3.1.1.3 Instruction Column in the Opcode Summary Table" explains:
attribute is 16 bits. The word general-purpose registers are: AX, CX, DX, BX, SP, BP, SI, DI.
Thus
mov ds, cs
is not encodable, as there is nomov Sreg, Sreg
version.阻止这些操作的实际上不是汇编语言,而是底层机器语言。
虽然汇编由易于阅读的单词或助记符组成,但它们实际上非常直接地表示机器代码的 1 和 0。 在 x86 CPU 上,每条指令通常由一系列字节组成,其中各个字节甚至字节中的位都具有含义。 某些位代表指令,其他位代表寻址模式。 在寄存器寻址模式(例如您的示例)中,某些位表示哪些特定寄存器将用作 mov 指令的源和目标。
现在,x86 系列处理器可以追溯到 20 世纪 70 年代,当时 CPU 架构更为简单。 在那些日子里,累加器的概念至关重要 -
ax
是 16 位 x86 累加器。 所有计算均在此寄存器中建立或“累积”,因此可供所有指令使用。 其他通用寄存器的使用范围更受限制。由于指令是基于字节的,因此您需要尽可能少的字节来表示指令,以保持指令解码速度快。 为了使尽可能多的指令尽可能短,累加器的使用成为中心。
在更现代的 CPU(例如 Motorola 680x0)上,更通用的寄存器具有更多以前属于累加器的功能。 在 RISC CPU 上,所有寄存器都像累加器一样灵活。 我听说在 64 位模式下,当前的 x86/amd64 指令集现在受到的限制要少得多。
It's not the assembly language really but the underlying machine language which prevents these operations.
While assembly is made up of easy to read words or mnemonics, they actually represent quite directly the 1s and 0s of the machine code. On x86 CPUs each instruction is typically made up of a sequence of bytes with individual bytes or even bits within the bytes having meaning. Certain bits represent the instruction, others represent the addressing mode. In register addressing modes such as your examples some bits represent which specific registers are to be used as the source and destination of the
mov
instruction.Now the x86 family of processors go back a long way to the 1970s when CPU architecture was simpler. In those days the concept of the accumulator was of key importance -
ax
is the 16-bit x86 accumulator. All calculations were built up or "accumulated" in this register so it was available to all instructions. Other general purpose registers had a more restricted range of use.Because instructions were based on bytes you wanted as few bytes to represent an instruction as possible to keep instruction decoding fast. To keep as many instructions as short as possible the use of the accumulator is made central.
On more modern CPUs such as the Motorola 680x0 more general purpose registers have more abilities that were previously the domain of the accumulator. On RISC CPUs all registers are as flexible as accumulators. I have heard that in 64-bit mode the current x86/amd64 instruction set is now much less restricted.