Assembly cmp时设置CF

Assembly cmp时设置CF,assembly,x86,Assembly,X86,当我们比较两个数字且一个数字小于另一个数字时,将设置标志CF: mov eax,1 cmp eax,2 jb truWay 以二进制形式: 1=00000001 2=00000010=11111101+1(add. code)=11111110и 00000001+11111110=11111111(no carry) 为什么指令cmp eax,2设置CF标志?没有结转,或者我错了。确实有借出CF 您的指令cmp执行以下减法: 1 = 0001 - 2 = 0010 --------

当我们比较两个数字且一个数字小于另一个数字时,将设置标志
CF

mov eax,1
cmp eax,2
jb truWay
以二进制形式:

1=00000001 
2=00000010=11111101+1(add. code)=11111110и 
00000001+11111110=11111111(no carry)

为什么指令
cmp eax,2
设置
CF
标志?没有结转,或者我错了。

确实有借出<如果存在借出,则由
cmp
指令设置code>CF

您的指令
cmp
执行以下减法:

  1 = 0001
- 2 = 0010
--------------
      1111
  10001
-  0010
-------
   1111
对于最右边的第一列,没有什么特别的:
1-0=1

对于最右边的第二列,有一个借阅(即:
1
是从下一列中的一列“借来的”)。需要借用,因为
0<1
。该列的结果是
10-1=1

但是,请注意,对于第一个操作数,左侧没有一列包含要借用的
1
,因此会发生借用:最高有效位的借用将出来,这实际上设置了
CF

减法操作实际上类似于设置
CF
(即:为第一个操作数的MSB“借用”或“获取”a
1
)并执行以下减法:

  1 = 0001
- 2 = 0010
--------------
      1111
  10001
-  0010
-------
   1111
请注意,第一个操作数在其真实MSB的左侧有一个
1
。此
1
以前不存在,它表示借用。

您可以参考以了解在ALU中如何执行减法

虽然A-B=A+(-B)是真的,而在二的补码中这是A+、B+1,但这种考虑只解释了结果

用半加法器实现的减法器采用以下形式

请注意,执行位是反向的

您可以通过示例(将大小限制为4位)检查这是否必要和正确:

1-2=1+(-2)=0001b+1110b=0 | 1111b,因为-0=1,我们有一个借款

而对于2-1,则有一个

2-1=2+(-1)=0010b+1111b=1 | 0001b,因为-1=0,我们没有借款

因此,在您的示例中,有一个借入,因此设置了CF,这正是因为0001b+1110b不产生进位

为了更正式地证明反向执行标志的正确性,可以使用一次对位数的归纳

基本情况
n=1

这可以用真值表来证明

a  b   a-b (a+¬b+1)  ¬carryOut  Expected borrow
0  0   0+1+1 = 1|0       0           0
0  1   0+0+1 = 0|1       1           1
1  0   1+1+1 = 1|1       0           0
1  1   1+0+1 = 1|0       0           0
诱导病例

当减去两个n位数字A=an-1时。。。a0和B=bn-1。。。b0我们可以有A>B,A 在第一种情况下,存在一个k,使得从k到n的所有j>k的ak ak 因此,A和B向下等于第k-1位,因此只有这么多位影响执行。
但根据归纳假设,执行是正确的,因此在这种情况下也是正确的

同样的过程也适用于A>B的情况


情况A=B更容易,因为整个操作减少到A+-A+1,这将减少到111…1+1,这将始终产生进货,因此不会产生借货。

首先:

a-b
的结果与
a+(-b)
的结果相同

但是,操作
a-b
设置的标志与操作
a+(-b)
设置的标志不一致(至少不总是如此)

通过比较不同的CPU类型(例如,现代x86 CPU和历史上的6502)可以看出这一点:

操作
a+b
后,x86和6502上的标志值相同,而操作
a-b
后,两个CPU上的“进位标志”的含义正好相反

这意味着在两个CPU上操作
a+(-b)
后,“进位标志”的值相同,而
a-b
后的值在两个CPU上始终不同

秒:

在x86上,减法运算的“进位标志”定义为“借出”。你可以通过

  • 将两个数字扩展为具有更多位的数字-例如9而不是8位
  • 然后将“扩展”数设为负数
  • 然后做加法
  • 忽略加法中的进位
  • 而是使用结果的最高位作为进位
例如:

1 = 00000001 (8 bit) = 0 00000001 (9 bit)
2 = 00000010 (8 bit) = 0 00000010 (9 bit)
3 = 00000011 (8 bit) = 0 00000011 (9 bit)
=> -2 = 1 11111110 (9 bit!)

Do the addition:
3 + (-2) = 1000000001 (9 bit plus carry)
1 + (-2) =  111111111 (9 bit)

Ignore carry:
3 + (-2) = 000000001 (9 bit)
1 + (-2) = 111111111 (9 bit)

Use the highest bit as carry:
3 + (-2) =  000000001 = 0 00000001 = (no carry) 00000001
1 + (-2) =  111111111 = 1 11111111 = (carry)    11111111

cmp减法,1-2需要一个carryCould,你用二进制的形式显示它?因为2大于1,所以你不能不借就减去。。。无需转换为二进制即可查看此内容;-)您应该真正阅读CMP的指令集参考,以便理解它的语义。