为什么在这个替换方程中设置进位标志?

时间:2017-09-01 15:28:25

标签: assembly x86 twos-complement

在此article中,它说明了以下内容:

  

1111 + 0001 = 0000(进位标志打开)

据我所知,当结果不符合一定数量的位(本例中为4位)时会发生进位,因此上面的公式确实导致了进位(因为结果有效{{1 },不适合4位)。

但请看同一篇文章中的以下内容:

10000

我不明白为什么在这种情况下设置进位标志,我的意思是结果是0000 - 0001 = 1111 (carry flag is turned on) ,所以它适合4位!

4 个答案:

答案 0 :(得分:2)

如果忽略类型的大小,那么

1111 + 0001 = 10000

这就是为什么你得到一个进位(只是为了表明结果大于存储的0)。如果必须添加其他(十六进制)“数字”,这很重要。

通过减法,您可以得到类似的问题:

0000 - 0001 = 1111

实际上说:0 - 1 = 15.这不是真的,所以进位被设置为表示已经执行了借位,即或多或少地执行了以下操作:

10000 - 0001 = 1111 (16 - 1 = 15)

当你用十进制减去时你会这样做:

    34
    18
  ---- -

要从4中减去8,你必须从下一个数字中借1,得到14 - 8 = 6.需要借用才能减去下一对高位数。 3 - 1 = 2,但你必须减去借用,所以现在3 - 1 - 借用= 1.这就是为什么你(正确)得到16而不是26的原因。

    34
    18
  ---- -
    16

二进制借用具有相同的功能:它存储在进位标志中并可以使用SBB(借用减去)而不是普通SUB减去(例如在x86汇编程序中)(减去)。进位标志的值(现在用作“借用标志”)还从两个操作数中减去:

Value1  DW      0x1234  ; alternatively: DB 0x34,0x12
Value2  DW      0x0678  ;                DB 0x78,0x06  
Result  DW      0

        MOV     AL,BYTE PTR [Value1]      ; 0011 0100
        SUB     AL,BYTE PTR [Value2]      ; 0111 1000
        MOV     BYTE PTR [Result],AL      ; 0xBC = 1011 1100, but a borrow was needed!
        MOV     AL,BYTE PTR [Value1 + 1]  ; 0001 0010
        SBB     AL,BYTE PTR [Value2 + 1]  ; 0000 0110 (0x12 - 0x06 - carry = 0x0B)
        MOV     BYTE PTR [Result + 1],AL  ; 0x0B = 0000 1011 

答案 1 :(得分:2)

在大多数CPU(包括x86 CPU)上,进位标志的行为方式如下 加法和减法:

进位标志是将数字的“长度”扩展一位时结果的最高位。

示例:

 1110 +  0011 = 01110 + 00010 (extending 4 bits to 5 bits)
01110 + 00011 = 10001 (5 bit result)
 1110 +  0011 =  0001, Carry=1 (highest of the 5 bits is the carry flag)

 0010 -  0011 = 00010 - 00010 (extending 4 bits to 5 bits)
00010 - 00011 = 11111 (5 bit result)
 0010 -  0011  = 1111, Carry=1 (highest of the 5 bits is the carry flag)

(但是有些CPU的进位标志在减法时有所不同;例如:历史性的6502)

答案 2 :(得分:1)

我们从小学就知道a - b = a +( - b)我们知道使用二进制补码来否定某些东西意味着反转并添加一个。有些人知道处理器不会减去它们的添加而是

  0000
 -0001
=======

真的是

      1
   0000
+  1110
========

反转并添加一个,因为无论如何我们必须携带,我们在那里添加一个 而不是做额外的工作。所以我们反转进位,并在进入加法器的路上反转第二个操作数。

  00001
   0000
+  1110
========
   1111

你是对的,这是答案,但有些处理器反转了执行,听起来就像你正在使用的那样做。为什么?因为如果你检查一些其他数字组,你会看到该位可以用作借位或非借用位而不是无符号溢出,这对于无符号数字意味着,就像在这种情况下一样。 0000 + 1111 = 1111,这不是无符号溢出。

所以从一个架构到下一个架构(ARM,MIPS,AVR,x86等),如果你想使用那个标志(而不是MIPS),你可以阅读文档,或者做一个实验,因为文档不是很好这个话题。有时带有借位指令的进位或减法的加法将暗示该结构的工作方式(在减去的路上反转进位标志)。

答案 3 :(得分:0)

所以你说这个等式...

addNeed() {
  this.needs.push(this.fb.group({ need: this.fb.control('') }));
}

...将“进位”标志设置为打开吗?

是的,这是因为执行加法时将在数据溢出时设置进位! 如果进行减法运算,则进位标志为借用标志。

正如您在Intels 8085 Programming Guide中所见,减法是对进位标志的补充!

How "SBB" works explained in Intel's 8085 Programming Guide!

该等式不产生进位,而是通过减法求补! 希望对您有帮助!