idl*_*n89 9 x86 assembly flags
目前,我为非常大的无符号整数编写了我自己的小库,用于算术和逻辑运算.为了提高性能,我决定在汇编中实现一些功能.所以这是我的问题.当减去两个无符号整数时,当我从0中减去任何数字时,将设置进位标志.
但是为什么Carry Flag会在这种情况下出现?进位标志仅在发生溢出时设置,但如果我从零中减去任何数字,则不会出现溢出.或者我错了?
Mar*_*oom 12
进位标志是最高有效位(MSb)的进位或借位:
CF(位0)进位标志 - 设置算术运算是否产生进位或借位的结果中最重要的位; 否则清除.该标志表示无符号整数运算的溢出条件.它也用于多精度算术.
不要将CF与符号位相关联,在减法CF中,只要被视为无符号的minuend小于减数,则将其设置为无符号.
这相当于溢出条件,对于带符号的数字,等效标志为OF.
对于(不必要的?)视觉线索,在这个4-5操作中,它是第二个借用,红色的,设置CF
如果你从零中减去,那么自然地说,对于任何数字,但是本身为零,你总是会设置CF,因为减数至少有一个位设置.
最后,一些指令允许您更改符号位而不影响CF(例如,参见逻辑运算或行为neg).
我们从小学就知道 a - b = a + (-b)。这就是我们不减去我们添加负数的逻辑。我们还从初学者编程课程中了解到,用二进制补码可以得到负数,反相加一个。a - b = a + (~b) + 1。我们也从小学就知道携带的概念。9+3 = 2 携带一个。二进制相同,有两个操作数,你可以让 1 + 1 = 0 携带一个。所以逻辑中的每一列都需要一个进位。每个都是三位进位出,两个操作数进位进位和结果出。由于这些逻辑 blob 中的每一个都有一个输入位,进位,第一个进位的正常加法是零,但对于减法,我们可以使进位为 1 并反转第二个操作数以获得 a + b = a + (~ b) + 1
所以减法就是加法,如果你通过一些简单的例子来工作,或者最好自己尝试每三位操作数的组合。您将看到没有符号或无符号加法(或减法)之类的东西,这是二进制补码编码的美妙之处。
知道这一切,减法就是加法,加法我们在UNSIGNED溢出时得到一个进位,有符号溢出位是当msbit的进位和进位不匹配时,通常表示为V标志。现在的一些架构,由于它们已经在输入时反转 b 操作数,并且在输入时反转进位,因此它们在输出时反转进位。有些不。因此,您必须查看您的特定体系结构以了解进位是被视为无符号加法溢出还是借位。或不借或其他什么。
零减去某些东西并不总是会进行加法运算。
0b000 - 0b111
0001
000
+ 000
=====
001
Run Code Online (Sandbox Code Playgroud)
加法的进位为零。您的架构可能会选择保留这种方式,也可能会选择将其反转并称之为借用。
在一个建筑家族中。所有 x86 或所有 ARM 很可能会永远继续以同样的方式做这件事。但是没有理由期望 ARM 和 MIPS 以及 x86 和 XYZ 都以相同的方式来做。
从术语的角度来看,反转它并将其定义为借用词是有道理的。
请注意,所有(有符号/无符号)大于、小于、大于或等于、小于或等于的定义都基于该架构的进位/借位选择,您无法跨架构转换这些标志比较,除非它们具有相同的定义。