Assembly 为什么mov指令直接使用ax而不是两段寄存器?

Assembly 为什么mov指令直接使用ax而不是两段寄存器?,assembly,x86,nasm,accumulator,addressing-mode,Assembly,X86,Nasm,Accumulator,Addressing Mode,我看到这样的代码: mov ax, cs mov ds, ax mov es, ax 为什么我不能将其压缩为: mov ds, cs mov es, cs 第一种方法使用累加器寄存器后是否更快?但这似乎并不直观,因为cs和ds是段寄存器。还是有一些我不知道的限制 顺便说一句,我正在使用nasm。你不能将段寄存器移动到段寄存器——它没有指令。处理器中只有这么多空间来容纳微码的所有指令。因此,对于很少使用的操作和更改段寄存器,通常首选一条通用指令,而不是多条专用指令。此外,对于某些处理器来说,指

我看到这样的代码:

mov ax, cs
mov ds, ax
mov es, ax
为什么我不能将其压缩为:

mov ds, cs
mov es, cs
第一种方法使用累加器寄存器后是否更快?但这似乎并不直观,因为cs和ds是段寄存器。还是有一些我不知道的限制


顺便说一句,我正在使用nasm。

你不能将段寄存器移动到段寄存器——它没有指令。

处理器中只有这么多空间来容纳微码的所有指令。因此,对于很少使用的操作和更改段寄存器,通常首选一条通用指令,而不是多条专用指令。此外,对于某些处理器来说,指令的数量绝对受到体系结构的限制——例如,最初的8080处理器被限制为256条指令,因为它们都必须将操作码编码在一个字节中。

真正阻止这些操作的不是汇编语言,而是底层机器语言

虽然汇编由易于阅读的单词或助记符组成,但它们实际上相当直接地表示机器代码的1和0。在x86 CPU上,每条指令通常由一个字节序列组成,每个字节或甚至字节中的位都有意义。某些位表示指令,其他位表示指令。在寄存器寻址模式(如示例)中,一些位表示哪些特定寄存器将用作
mov
指令的源和目标

现在x86系列处理器可以追溯到20世纪70年代,那时CPU体系结构更简单。在那些日子里,ax的概念非常重要-
ax
是16位x86累加器。所有计算都是在该寄存器中建立或“累积”的,因此所有指令都可以使用该寄存器。其他通用寄存器的使用范围更为有限

因为指令是基于字节的,所以您希望尽可能少的字节来表示指令,以保持指令解码速度。为了使尽可能多的指令尽可能简短,蓄能器的使用被置于中心位置

在更现代的CPU(如摩托罗拉680x0)上,更多的通用寄存器具有更多以前属于累加器的功能。在RISC CPU上,所有寄存器都像累加器一样灵活。我听说在64位模式下,当前的x86/amd64指令集的限制要小得多。

查看“MOV Move”列“指令”

只有16位mov to寄存器编码为:

mov r/m16, Sreg
“操作码汇总表中的3.1.1.3说明栏”说明:

  • r/m16—一种字通用寄存器或内存操作数,用于操作数大小为的指令 属性为16位。字通用寄存器为:AX、CX、DX、BX、SP、BP、SI、DI
  • Sreg-段寄存器

因此,
mov-ds,cs
是不可编码的,因为没有
mov-Sreg,Sreg
版本。

当我第一次阅读你的回复时,我不相信你,但在NASM的文档中,确实没有mov-reg\u-dseg,reg\u-cseg指令。这不是原因,而是结果。什么?我不明白你的意思,尼尔。问问你自己为什么x86没有这些特别的说明。@Neil-实际上这就是“为什么书的作者没有mov ds,cs?”的答案,更具体地说,是他的问题“有一些我不知道的限制吗?”然而,下一个自然的问题是“wtf,为什么没有?”所以你的答案很有帮助。直到x86_64,寄存器才能像那样使用。由于32位x86,大多数寄存器或多或少都可以充当通用寄存器。看起来我不知道问题是关于段寄存器和累加器的。我从来没有进入过x86汇编,因为内存的工作方式很糟糕,但后来使用了段寄存器之类的东西。我相信现在有了一个很好的平面内存模型,在这里工作会更好。我也不太喜欢x86汇编。但是x86上仍然有段指令。x86的地址空间不是平坦的,它比这更复杂。几代人以来添加了各种模式,各种操作系统并不总是使用当时最强大的可用模式。x86 CPU为向后兼容性保留了大量内容。如今,在现代操作系统上,你不必担心细分市场。这就是我所说的“平面内存模型”。我不知道这些天段寄存器使用了多少,或者它们是否必要,或者它们是否只是保留了旧名称的通用寄存器……你的第一段是可靠的,但其余部分是粗略的。可以使用任何GP整数寄存器或寻址模式作为非Sreg操作数。它们不仅限于AX。一般来说,即使是8086也可以使用与添加ax、cx操作码相同的操作码来执行添加bx、cx等操作,只是操作数的ModRM字节编码中的不同目的地。x86不是累加器机器。AX对于8086上的某些操作是特殊的,但不是最基本的ALU。(与8080不同,
A
更为特殊)。386使机器代码中的无AX特殊编码空间对于8086也是一个问题。大概他们想为未来的扩张留下空间。除了微码空间之外,解码器硬件的复杂性也支持解码更多不同的操作码。(除非8086解码本身是由微码IDK完成的)。但是,是的,将一个操作码花在一个很少使用的指令上(当它被使用时)只会节省1个2字节的指令,而另一种选择是不值得的。