SUB指令的目的是什么?

时间:2015-03-22 10:36:38

标签: assembly x86

我自己学习集会,我有一个混乱,我想清楚。

因此,根据我的理解,x86计算机使用相同的电路进行加法和减法。对于减法,将负数转换为其2补码,然后可以使用加法电路来执行减法。例如:等式4 - 2转换为4 + (-2)

因此,如果可以使用2补语进行减法,那么SUB指令的目的是什么?

2 个答案:

答案 0 :(得分:10)

在2的补码世界中,可以通过取1的补码(所有位反转)并加1来获得整数的否定。例如,在8位世界中:< / p>

A:   0x00000002    ; my number
~A:  0xFFFFFFFD    ; 1's complement of my number
-A:  0xFFFFFFFE    ; 2's complement of my number (negative A)

要减去A-B,我们肯定可以添加否定的A+(-B)

NOT  B              ; invert each bit in the 8-bit value, B
ADD  B, 1           ; add 1, giving the 2's complement negated B
ADD  A, B

当然,在我添加之前,我必须修改B(否定它)。如果我希望B保持完好怎么办?

PUSH B              ; save B
NOT  B              ; invert each bit in the 8-bit value, B
INC  A              ; add 1, giving the 2's complement negated B
ADD  A, B
POP  B              ; restore B

或者

NOT  B              ; invert each bit in the 8-bit value, B
INC  A              ; add 1, giving the 2's complement negated B
ADD  A, B
NOT  B              ; restore B

这样有效。但是,如果只有SUB指令会更容易吗?

SUB  A, B

如果您正在编写汇编语言以进行大量算术运算,您更喜欢哪种方法?并且,在第一种情况下,我使用了INC A指令。我可以在没有INC的情况下离开,只使用ADD A, 1。但是,许多微处理器上的ADD A, 1要求我从指令存储器中取出更多以执行以获得立即1值。因此,提供INC,因为这样的操作是如此常见。

当微处理器设计人员确定要使用的指令集时,他们会考虑最常用的操作类型。减法很常见,因此SUB指令非常方便。因此,它几乎存在于您可以找到的任何指令集中。指令集中还有其他指令,其存在的原因不太明显。例如,x86具有XLAT指令,以及所有&#34;字符串&#34;说明,LODSSTOS等。当我可以使用MOVINC等完成所有工作时,为什么它们存在?因为有人认为这些操作很常见,值得单一指令。

因此,SUB指令背后的目的,就像CPU实现的许多其他指令一样,是提供更快(执行时间)和更简单的方式来执行最常在软件中执行的操作,与事实平衡对于可以实施的指令数量存在实际限制。

答案 1 :(得分:8)

TL; DR

因为它是最常见的操作之一,所以有专门的指令可以帮助提高速度。设计师知道如何快速实现,并且不需要单独的否定


来自着名的计算机架构书籍Computer Organization and Design, Fourth Edition: The Hardware/Software Interface,David A. Patterson和John L. Hennessy以及Digital Design and Computer Architecture,David Money Harris,Sarah L. Harris,我们知道MIPS的设计原则如下

  1. 设计原则1:简洁有利于规律性。
  2. 设计原则2:快速完成常见案例。
  3. 设计原则3:更小更快。
  4. 设计原则4:良好的设计需要良好的妥协。
  5. 在其他架构中,这些也是正确的。在x86和许多其他(主要是较旧的)体系结构中,由于向后兼容性,有些无法实现,但主要要点适用。

    由于1 st 和3 rd 原则,我们需要使指令集尽可能紧凑并且不要创建如果我们可以使用其他说明进行新的说明。但是,根据原则2和4,我们需要尽可能快地进行常规操作

    实际上大多数指令都是多余的,因为我们只能使用one instruction作为图灵完整指令集。 x86本身不是一个OISC架构,但它仍然可以只用一个movadd / sub 做任何事情,因为它们是{{3} }。甚至还有一个编译器可以将有效的C代码编译到只有 MOV 的程序中(或者只有 XOR,SUB,ADD,XADD,ADC,SBB,AND / OR,PUSH / POP,名为proved to be Turing-complete

    的1位移位或CMPXCHG / XCHG

    因此,使用addsub,我们可以轻松获得移位,按位运算和乘法/除法。但是,这些基本操作可能需要非常长的一系列指令才能进行模拟,用户也不会对此感到满意。

    这就是为什么制造商不断向新的微结构添加新指令的原因,因为新的需求会使得在开始使用之前不常见。例如,当3D应用程序成为新趋势时,他们决定为矢量和3D操作添加movfuscator,并且矩阵运算也很常见。然后,当提高安全性要求使加密更加普遍时,引入了SIMD instructions来增强加密应用程序。但这还不够,因为密码学和许多其他应用程序使用了大量的多精度算术,英特尔添加AES instructions来加快速度。现在,您将看到加速AI操作的指令开始进入架构


    回到主要问题,减法是非常常见的,因此值得一个单独的指令。没有它,你将需要negate一个操作数,然后add,这至少要花费两倍的时间和指令空间。 sub a, b优于neg b; add a, b

    然而减法并不一定会因为您的想法而变得更慢,因为设计师使用一个聪明的技巧让加法器在相同的时钟数下同时执行addsub 仅添加MULX/ADOX/ADCX instructions和NOT门以及新输入 Binvert ,以便有条件地反转第二个输入,如下所示

    muxer

    adder

    基本它通过实现两个补码-b = ~b + 1来实现,所以a - b = a + ~b + 1。这意味着我们只需要将进位设置为1(或者取消进位的进位)并反转第二个输入。

    我在开头提到的那本书中也提到了这种Computer Architecture - Full Adder。不幸的是,由于授权问题,我无法引用它,但我在教授的另一本书中找到了。帕特森和教授。轩尼诗:

    ALU

    RISC-V ALU

    正如您所看到的,通过另一个非常简单的修改,他们现在可以使用单个ALU执行6种不同的操作:add,sub,slt,和,或者

    Computer Organization and Design RISC-V Edition: The Hardware Software Interface

    6-function ALU

    您可以在ALU设计课程中找到更多信息,或在Google上找到关键字Binvert / Bnegate