Math 没有溢出标志的处理器如何执行有符号算术?

Math 没有溢出标志的处理器如何执行有符号算术?,math,assembly,signed,integer-arithmetic,8085,Math,Assembly,Signed,Integer Arithmetic,8085,我知道,两个大于给定处理器总线大小的无符号整数相加可以通过进位标志实现。通常,使用溢出标志的有符号整数也是如此。然而,Intel 8085只拥有一个符号标志,而不是溢出标志,那么它如何处理有符号整数算法呢 如您所知,溢出标志仅与有符号整数算术相关。在ALU同时具有溢出和进位标志(如x86)的处理器上,这两个标志都是根据二进制算术运算的结果设置的,但如何解释它们则取决于程序员。有符号算术使用溢出标志;无符号算术使用进位标志。看错了,你会得到毫无意义的数据 有两种情况下,溢出标志将在二进制算术运算期

我知道,两个大于给定处理器总线大小的无符号整数相加可以通过进位标志实现。通常,使用溢出标志的有符号整数也是如此。然而,Intel 8085只拥有一个符号标志,而不是溢出标志,那么它如何处理有符号整数算法呢

如您所知,溢出标志仅与有符号整数算术相关。在ALU同时具有溢出和进位标志(如x86)的处理器上,这两个标志都是根据二进制算术运算的结果设置的,但如何解释它们则取决于程序员。有符号算术使用溢出标志;无符号算术使用进位标志。看错了,你会得到毫无意义的数据

有两种情况下,溢出标志将在二进制算术运算期间打开:

  • 两个输入的符号位均为off,而结果的符号位为on
  • 两个输入的符号位均为on,而结果的符号位为off
  • 基本上,当结果的符号位与输入操作数的符号位不匹配时,就会设置溢出标志。在所有其他情况下,溢出标志将关闭

    举几个例子:

    • 0100+0001=0101(溢出标志关闭)
    • 0100+0100=1000(溢出标志打开)
    • 0110+1001=1111(溢出标志关闭)
    • 1000+1000=0000(溢出标志打开)
    • 1000+0001=1001(溢出标志关闭)
    • 1100+1100=1000(溢出标志关闭)
    请注意,溢出标志的状态仅取决于三个数字的符号位;因此,您只需查看这些位。这是很直观的。如果你把两个正数相加得到一个负数,那么答案一定是错的,因为两个正数应该得到一个正的结果。相反,如果你加上两个负数,得到一个正数,那也一定是错的。正数加负数永远不会溢出,因为总和位于两个输入值之间。因此,混合有符号值的算术永远不会打开溢出标志

    (显然,这一切都假设了二的补码运算。)

    因此,即使处理器的ALU没有自动为您计算溢出标志的状态,您也可以轻松地计算溢出标志的状态。您所需要做的就是查看三个值的符号位,特别是符号位的二进制进位和符号位的二进制进位。当一个位被带进符号位而没有相应的执行时,就会发生溢出

    这些C函数实现以下逻辑:

    //对于两个有符号整数的二进制(二的补码)加法,
    //如果输入具有相同的符号,并且
    //结果的符号与输入的符号不同。
    bool GetOverflowFlagForAddition(int op1、int op2、int result)
    {
    返回(~(op1^op2)和(op1^result))<0;
    }
    //对于两个有符号整数的二进制(二的补码)减法,
    //如果输入具有相同的符号,并且
    //结果的符号与输入的符号匹配。
    bool GetOverflowFlagForSubtraction(int op1、int op2、int result)
    {
    返回((op1^op2)和(op1^result))<0;
    }
    
    (当然,你可以用很多不同的方法来写这篇文章。)

    或者,用“溢出可以定义为符号位进位和进位的异或”这一术语来表述。如果进位不等于该特定(最左边)位的进位,则会发生溢出

    更正式的定义是溢出标志是结果高两位执行的异或。象征性地,对于8位值:O=C6^C7,其中O表示“溢出”,而C表示“进位”。这只是对我已经给出的定义的重申:如果进位与进位不同,则会发生溢出(在本例中为第7位)

    另请参见(这是在6502的上下文中,另一种流行的8位处理器)


    好吧,那么携带旗是什么意思?进位标志表示无符号算术中的溢出情况。再次出现两种设置的情况:

  • 如果最高有效位(符号位)有进位,则在加法期间设置进位标志

  • 如果存在到最高有效位(符号位)的借用,则在减法过程中设置进位标志

  • 在所有其他情况下,进位标志关闭。同样,例子如下:

    • 1111+0001=0000(带进位标志)
    • 0111+0001=1000(进位标志关闭)
    • 0000-0001=1111(携带标志打开)
    • 1000-0001=0111(进位标志关闭)
    为了避免不明显,它需要明确指出减法与两个补码否定的加法相同,因此后两个例子可以用加法改写为:

    • 0000+1111=1111(进位标志打开)
    • 1000+1111=0111(进位标志关闭)
    …但请注意,减法进位是加法进位集的倒数


    将所有这些放在一起,您就完全可以在进位和符号标志方面实现溢出标志。如果有最高有效位(符号位)的进位,则设置进位标志。如果结果设置了符号位,则设置符号标志,这意味着最高有效位有进位。根据我们上面对溢出标志的定义,of==CF^SF,因为溢出是符号位的进位与符号位的进位异或。如果进位不等于进位,则发生有符号溢出

    然而,有趣的是,肯·谢里夫的研究表明,事实上,它确实有一个