Assembly 为什么在减法过程中设置进位标志,而0是小数点?

Assembly 为什么在减法过程中设置进位标志,而0是小数点?,assembly,x86,flags,Assembly,X86,Flags,目前,我为非常大的无符号整数编写了自己的算术和逻辑运算小库。为了提高性能,我决定在汇编中实现一些函数。这是我的问题。 在减去两个无符号整数时,当我从0中减去任何数字时,将设置进位标志 但为什么在这种情况下会设置进位标志?进位标志仅在发生溢出时设置,但如果从零减去任何数字,则不会得到溢出。 或者我错了?进位标志是最高有效位(MSb)的进位或借位: CF(位0)进位标志-如果算术运算生成结果最重要位的进位或借位,则设置该标志;否则的话。此标志指示的溢出情况 无符号整数算术。它也用于多精度算法 不要将

目前,我为非常大的无符号整数编写了自己的算术和逻辑运算小库。为了提高性能,我决定在汇编中实现一些函数。这是我的问题。 在减去两个无符号整数时,当我从0中减去任何数字时,将设置进位标志

但为什么在这种情况下会设置进位标志?进位标志仅在发生溢出时设置,但如果从零减去任何数字,则不会得到溢出。
或者我错了?

进位标志是最高有效位(MSb)的进位或借位:

CF(位0)进位标志-如果算术运算生成结果最重要位的进位或借位,则设置该标志;否则的话。此标志指示的溢出情况 无符号整数算术。它也用于多精度算法

不要将CF与符号位关联,在减法中,只要视为无符号的分钟数小于视为无符号的减数,就会设置CF。
这相当于溢出条件,对于有符号数字,等效标志为

对于一个(不必要的?)视觉线索,在这个4-5操作中,设置CF的是第二个借用,即红色借用

不是从零减去,而是自然地,对于任何数字,除了零本身,你总是有CF集,因为减数至少有一个位集



最后,一些指令允许您在不影响CF的情况下更改符号位(例如,请参见逻辑运算或
neg
)。

我们从小学就知道a-b=a+(-b)。这就是逻辑的原理,我们不减,我们加负数。我们还从初学者编程课上了解到,用两个补码来得到负数,你可以倒过来加一个。a-b=a+(~b)+1。我们也从小学就知道携带的概念。9+3=2代表1。在二进制中相同,对于两个操作数,可以让1+1=0携带一个。所以逻辑中的每一列都需要一个进位。每一个都是三位入两位出,两个操作数加上进位和进位,以及结果输出。由于这些逻辑BLOB中的每个逻辑BLOB都有一个输入位,进位,第一个进位是零的普通加法,但对于减法,我们可以将进位设为1,然后将第二个操作数反转,得到a+b=a+(~b)+1

所以减法就是加法,如果你学习一些简单的例子,或者最好自己尝试每三位操作数的组合。您将看到,没有有符号或无符号加法(或减法)这类东西,这是两个补码编码的美妙之处

知道了所有这些,减法就是加法,通过加法我们得到一个无符号溢出的进位,有符号溢出位是当msbit的进位和进位不匹配时,通常表示为V标志。现在有些体系结构,因为它们已经在传入时反转b操作数,在传入时反转进位,所以它们在传出时反转进位。有些人没有。因此,您必须查看特定的体系结构,以了解执行是被视为无符号加法溢出还是借用。或者不借钱什么的

零减去某个值,加法并不总是要执行

0b000 - 0b111

 0001
  000
+ 000
=====
  001
加法的进位为零。您的体系结构可以选择将其保留为这种方式,也可以选择将其反转并称之为借用

在建筑家族中。所有的x86或所有的ARMs都可能永远以同样的方式运行。但是没有理由期望ARM和MIPS以及x86和XYZ都以同样的方式来实现

从术语的角度来看,将其倒置并定义为借用是有意义的


请注意,所有(有符号/无符号)大于、小于、大于或等于、小于或等于的定义都基于该体系结构的进位/借位选择,除非这些标志比较具有相同的定义,否则无法跨体系结构转换它们。

注意:在汇编中编写自己的操作可能无法提供预期的优化。编译器不会检查内联程序集,也无法对其进行优化。如果您只提供逻辑C代码,您可能会发现编译器在优化方面会做得更好。谢谢您的建议。但我不做内联汇编。我在汇编中编写单独的部分,并将此目标文件与C代码链接。这样,在代码的整体结构中,汇编程序例程的优化机会就更少了。不要误解我的意思,我并不是在尝试使用汇编程序来提高速度,我曾经认为它也会更快,但始终要将使用链接汇编的代码的性能与使用完全优化编译器的C语言编写的代码的性能进行比较(
-O3
(对于gcc版本>=4.6.0的大多数
-Ofast
). 今天的编译器在优化方面做得很好,比C快9/10倍。好的,谢谢,我会记住这一点。我遇到的最大问题是,在C中没有简单的方法来检查进位标志的状态,并在进一步的操作中使用它。所以现在我使用无符号整数类型的最高有效位作为进位标志。但我对此并不满意。这就是为什么我想在汇编程序中实现减法和加法的核心逻辑。但也许有人有更好的办法。我总是乐于接受其他建议。谢谢你详细的回答。我的问题是我对借贷一无所知。我认为减法时的标志设置方式与加法时的标志设置方式相同。但现在我意识到这是错误的。在x86 arch上,进位标志设置为相反方向。(子)4-5=CF(1)。(加上)4+(-5)=CF(0)。@idlmn89: