Assembly 为什么是xor';不允许使用DS吗?

Assembly 为什么是xor';不允许使用DS吗?,assembly,x86,real-mode,Assembly,X86,Real Mode,我正在用实模式x86汇编编写一个程序,我正在尝试这样做: xor %ds, %ds 代替替代方案: mov $0, %ax mov %ax, %ds 但是,我遇到了一个汇编程序错误: Error: operand type mismatch for `xor' 为什么会这样?有没有办法避免这种情况以减少代码大小?对于异或指令,不允许将段寄存器作为第一个或第二个操作数。只能使用通用寄存器、内存位置和立即数 有没有办法绕过这个问题来减少代码大小 最短的路径似乎是: xor %ax, %ax m

我正在用实模式x86汇编编写一个程序,我正在尝试这样做:

xor %ds, %ds
代替替代方案:

mov $0, %ax
mov %ax, %ds
但是,我遇到了一个汇编程序错误:

Error: operand type mismatch for `xor'
为什么会这样?有没有办法避免这种情况以减少代码大小?

对于异或指令,不允许将段寄存器作为第一个或第二个操作数。只能使用通用寄存器、内存位置和立即数

有没有办法绕过这个问题来减少代码大小

最短的路径似乎是:

xor %ax, %ax
mov %ax, %ds
如果我没有犯错误,这比使用
mov$0,%ax
的变量短一个字节


您知道为什么他们选择不允许段寄存器作为异或的操作数吗?知道这一点很有意思

我怀疑CPU的设计者是否打算将操作
xor%ax,%ax
用于寄存器的归零。相反,CPU设计人员希望能够将
xor
ax寄存器与任何其他寄存器一起注册

而且,由于不允许将
xor
-ing
ax
与自身一起使用会更加困难,因此CPU不仅允许对两个不同寄存器(如
xor%bx,%ax
)进行操作,而且还允许对两个参数使用相同寄存器的操作

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

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

只有极少数情况下,使用内存段进行算术(或按位)操作才有意义。一个例子是,如果阵列长度超过64 KiB,则增加一个;在这种情况下,
add
操作可能很有用

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


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

没有带段寄存器的异或操作数;有关详细信息,请参阅指令集参考。如果要缩短代码大小,可以执行
pushw$0;popw%ds
。这仍然需要两个字节。实际上是三个字节。我认为没有更短的解决方案。就我而言,有一个更短的版本:
mov%cs,%ds
。由于程序的数据与程序驻留在相同的空间中,因此它们本质上应该是相同的值。这也行不通,因为MOV指令没有编码,其中两个操作数都是段寄存器。您可以执行
推送%cs;弹出两个字节的%ds
。请注意,如果您正在编写引导扇区,则假定CS为0是一个常见错误。您知道为什么他们选择不允许段寄存器作为异或的操作数吗?知道这一点很有意思。不过,回答为什么部分相对容易。这将需要一个额外的位来编码一个寄存器,这将不能很好地适应可用空间(modrm、sib、操作码)。加上该位的“四分之一”将被浪费,因为只有六个段寄存器。所有这些都是为了实现一个无用的功能:即使在过去,段寄存器也很少更改。对它们进行算术运算会将它们提升到GP寄存器,但仍然无法更改
cs
ds
ss
,因为它们经常被使用。这将使
es
fs
gs
成为唯一的优势。这不值得。。。。。。在更实际的方面,8086的段寄存器可能未连接到ALU,而仅用于使用专用加法器+移位器计算线性地址。不过这只是猜测。他们可以用alu或alu连接或微编码他们想要的任何东西。你不可能拥有所有你可能希望它不适合的东西,永远不会被调试,你也负担不起。就指令集而言,x86并不是一种您想要欣赏的体系结构,有许多体系结构值得研究,几乎所有其他体系结构都值得研究。值得钦佩的是,他们将这项技术保留了多久,以及他们如何不断地重新发明勇气,以保持它的相关性,并以它所使用的能量表现得更好。甚至更好的是,intels在发明和继续推动这项技术方面发挥了作用,尽管他们使用这项技术的旗舰产品。visual6502,阅读pdp-11及其前身,以及其他一些值得思考的有趣事情。为什么准将没有继续统治。为什么施乐没有接管并拥有计算机世界,这几乎是他们发明的。阿塔里,等等……这些都是有趣的问题。这实际上并不能回答问题本身;这只是针对我的一个评论。这个问题的答案在@fuz的第一个评论中。剩下的只是一个额外的好处:)不是为了设计更便宜的CPU,而是因为他们不想在非常特殊的指令上浪费操作码编码空间,这些指令的功能可以通过任何GP整数寄存器在几个额外的字节内复制。最初的8086为更多的操作码留出了一些空间,并使事情变得简单
0F
2字节操作码的转义字节出现得比较晚,IIRC,所以是的,这是8086的一项成本节约措施,但后来x86 CPU添加段寄存器add/sub/xor的原因是它很少需要
mov SR,imm16
本来是第一优先考虑的,但我们甚至没有。@PeterCordes他们本可以用
repz
前缀取代
ax dx
cs ss
repnz
取代
si bp
来设计8086。指令
repz add cx,si
将被解释为
add ds,si
repnz add si,cx
将被解释为