为什么不允许Xor'ing DS?

JL2*_*210 -1 x86 assembly real-mode

我正在以实模式x86程序集编写程序,并且正在尝试执行以下操作:

xor %ds, %ds
Run Code Online (Sandbox Code Playgroud)

而不是替代:

mov $0, %ax
mov %ax, %ds
Run Code Online (Sandbox Code Playgroud)

但是,出现汇编错误:

Error: operand type mismatch for `xor'
Run Code Online (Sandbox Code Playgroud)

为什么是这样?有没有办法解决这个问题以减少代码大小?

Mar*_*nau 5

有没有办法解决这个问题以减少代码大小?

最短的方法似乎如下:

xor %ax, %ax
mov %ax, %ds
Run Code Online (Sandbox Code Playgroud)

如果我没有记错的话,这比使用的变体短一个字节mov $0, %ax

您知道为什么他们选择不允许段寄存器作为操作数xor吗?知道这将很有趣。

我怀疑CPU的设计者是否打算将该操作xor %ax, %ax用于将寄存器清零。相反,CPU设计人员希望xorax寄存器可以与其他任何寄存器一起使用。

而且,因为它会一直比较困难,不要让xor-ing ax与本身的CPU不仅允许在两个不同的寄存器(如操作xor %bx, %ax),而且使用相同的寄存器用于两个参数的操作。

对于段寄存器,这是不同的:

段寄存器的唯一目的是存储一个内存段。这些寄存器不用于存储任何其他类型的信息。

在极少数情况下,使用内存段进行算术(或逐位)运算才有意义。例如,如果阵列的长度大于64 KiB,则添加一个实例。在这种情况下,add操作可能会有用。

但是,在大多数情况下,您不会对代表内存段的值执行算术运算。

我认为,出于这个原因,CPU的设计者决定不提供任何算术运算,因此他们可以设计更便宜的CPU(请参阅Margaret Bloom的评论)。

  • @PeterCordes他们本可以设计8086的方式是,repz前缀用cs-ss替换ax-dx,repnz替换si-bp。指令“ repz add cx,si”将被解释为“ add ds,si”,而“ repnz add si,cx”将被解释为“ add ds,cx”。这不会浪费操作码中的任何字节,通过较少的操作和较少的字节就可以进行很多操作(例如,使用“巨大”的数组),但是CPU的成本要高得多。 (4认同)