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“借用”或“获取”a1
)并执行以下减法:
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但根据归纳假设,执行是正确的,因此在这种情况下也是正确的 同样的过程也适用于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的指令集参考,以便理解它的语义。