Assembly 为什么cmp指令中的参数顺序很重要?

Assembly 为什么cmp指令中的参数顺序很重要?,assembly,x86,att,Assembly,X86,Att,我想知道为什么cmp指令需要参数顺序的特定条件 例如,我已经尝试了这两种方法 cmpl%eax,$'A' cmpl$'A',%eax 第一行返回错误,表示操作数类型不匹配。 第二条线运行良好 我看了《英特尔IA-32手册》,但它无法回答我的问题。它只是说参数1和2之间的减法,而不是每个参数应该有哪些类型 我想知道为什么第一行代码返回的操作数类型不匹配,而第二行没有。机器代码指令只支持带有立即数的方向。如果你没找到这个,你找错地方了。英特尔第二卷手册详细介绍了每种指令的所有可用编码 请记住,程序集

我想知道为什么cmp指令需要参数顺序的特定条件

例如,我已经尝试了这两种方法

cmpl%eax,$'A' cmpl$'A',%eax 第一行返回错误,表示操作数类型不匹配。 第二条线运行良好

我看了《英特尔IA-32手册》,但它无法回答我的问题。它只是说参数1和2之间的减法,而不是每个参数应该有哪些类型


我想知道为什么第一行代码返回的操作数类型不匹配,而第二行没有。机器代码指令只支持带有立即数的方向。如果你没找到这个,你找错地方了。英特尔第二卷手册详细介绍了每种指令的所有可用编码

请记住,程序集限制不是任意的源代码级别选择;它不是一种像C++那样的语言,它是描述机器代码的一种方式。 大多数ALU指令都会编写它们的目的地,特别是那些可以追溯到8086年的指令,所以它不可能是即时的。e、 g.低于%eax,$123显然毫无意义。因此,机器码格式的一致性/解码的简易性是没有直接目的地的特殊cmp操作码的原因之一。如果汇编器将该操作码映射到同一cmp助记符而不是不同的反向cmp助记符,则汇编语法也将不规则

相比之下,cmp r/m32、r32和cmp r32、r/m32都存在,因此您可以在任意方向将内存与寄存器进行比较。同样,这与其他ALU指令(如add和sub)的模式是一致的,因此这对于机器代码中更规则的解码/模式也是有意义的

如果使用jcc对结果进行分支,则始终可以交换操作数并使用相反的条件。不过,有时您希望CF设置为某种方式来馈送adc或sbb,所以有时这会带来不便

但这并不足以让8086指令集的架构师斯蒂芬·莫尔斯(Stephen Morse)使用为数不多的几个未使用的操作码中的一个,与cmp的即时编码进行反向比较

可以理解的是,像ARM那样的反向减法或反向比较指令,即dst=src-dst而不是dst-=src,但x86的可变长度机器码格式意味着只有这么多的1字节操作码。这可能只是又一条正常的即时ALU指令

或者实际上还有5个操作码,包括2个专用字节,如果我们遵循正常ALU指令的模式:正常的op r/m8、imm8、op r/m16、sign_extended_imm8、op r/m16、imm16以及AL、imm8和AX、imm16短格式,没有ModRM字节。我想对于非立即数操作数,助记符可以是操作数反转的cmp的别名,因此我们不需要在两个方向上都使用这4个操作码8和16位


ARM后来出现并使用了固定宽度的32位指令字,因此有相当多的操作码编码空间可用于诸如反向比较和反向减法之类的有用指令。

机器码指令仅支持立即数的方向。如果你没找到这个,你找错地方了。英特尔第二卷手册详细介绍了每种指令的所有可用编码

请记住,程序集限制不是任意的源代码级别选择;它不是一种像C++那样的语言,它是描述机器代码的一种方式。 大多数ALU指令都会编写它们的目的地,特别是那些可以追溯到8086年的指令,所以它不可能是即时的。e、 g.低于%eax,$123显然毫无意义。因此,机器码格式的一致性/解码的简易性是没有直接目的地的特殊cmp操作码的原因之一。如果汇编器将该操作码映射到同一cmp助记符而不是不同的反向cmp助记符,则汇编语法也将不规则

相比之下,cmp r/m32、r32和cmp r32、r/m32都存在,因此您可以在任意方向将内存与寄存器进行比较。同样,这与其他ALU指令(如add和sub)的模式是一致的,因此这对于机器代码中更规则的解码/模式也是有意义的

如果使用jcc对结果进行分支,则始终可以交换操作数并使用相反的条件。不过,有时您希望CF设置为某种方式来馈送adc或sbb,所以有时这会带来不便

但这并不足以让8086指令集的架构师斯蒂芬·莫尔斯(Stephen Morse)使用为数不多的几个未使用的操作码中的一个,与cmp的即时编码进行反向比较

可以理解的是,像ARM那样的反向减法或反向比较指令,即dst=src-dst而不是dst-=src,但x86的可变长度机器码格式意味着只有这么多的1字节操作码。这可能只是又一条正常的即时ALU指令

或actu 如果我们遵循普通ALU指令的模式,则再添加5个操作码,包括2个专用字节:普通的op r/m8、imm8、op r/m16、符号扩展的op r/imm8、op r/m16、imm16以及AL、imm8和AX、imm16不带ModRM字节的缩写形式。我想对于非立即数操作数,助记符可以是操作数反转的cmp的别名,因此我们不需要在两个方向上都使用这4个操作码8和16位


ARM后来推出并使用了固定宽度的32位指令字,因此在诸如反向比较和反向减法等有用指令上有相当多的操作码编码空间。

英特尔手册明确指出,第一个操作数必须是寄存器或内存操作数。由于您使用的是AT&T语法,因此操作数的顺序是相反的,$'A'既不是寄存器也不是内存操作数。英特尔手册明确规定,第一个操作数必须是寄存器或内存操作数。因为您使用的是AT&T语法,所以操作数的顺序是相反的,并且$'A'既不是寄存器也不是内存操作数。