大会比较标志的理解

时间:2012-12-31 11:36:34

标签: assembly

我正在努力理解汇编程序中的以下代码片段:

if ( EAX >= 5 )
  EBX = 1;
else
  EBX = 2;"

在汇编程序中,这是(根据我的书):

1     cmp eax, 5       ;(assuming eax is signed)
2     js signon        ;goto signon if SF = 1
3     jo elseblock     ;goto elseblock if OF = 1 and SF = 0
4     jmp thenblock    ;goto thenblock if SF = 0 and OF = 0
5 signon:
6     jo thenblock     ;goto thenblock if SF = 1 and OF = 1
7 elseblock:
8     mov ebx, 2
9     jmp next
10 thenblock:
11    mov ebx, 1
12    next:

我可以理解,结果标志可以是:(if(EAX> = 5)):

SF = 0& OF = 0 但是我无法理解旗帜是怎样的: SF = 1& OF = 1?什么计算给出了这个?

澄清我的意思:

如果eax处于较低的负极限,它可能会通过减去5而溢出到正值。如果它处于上限正值,它不能通过减去5而溢出到负值?

谢谢!

2 个答案:

答案 0 :(得分:1)

根据3位数字更容易想到这些,它都可以扩展。嗯,如果这是签名的(你没有在你的高级代码中指定/发布)那么四位是更好的,因为你使用了5.走过5附近的数字(这显示了alu的输出)

cmp reg,5
0111 - 0101 = 0111 + 1010 + 1 = 10010
0110 - 0101 = 0110 + 1010 + 1 = 10001
0101 - 0101 = 0101 + 1010 + 1 = 10000
0100 - 0101 = 0100 + 1010 + 1 = 01111
0011 - 0101 = 0011 + 1010 + 1 = 01110

现在您必须了解硬件的工作原理。当你进行减法时,一些处理器系列会反转来自alu的进位标志,其他处理器不会。无论哪种方式,你都可以在5 - 5点看到状态变化。而且你无论如何都不需要进位标志,代码也不使用它。

如果您正在进行签名数学,那么也尝试一些负数。

0000 - 0101 = 0000 + 1010 + 1 = 01011  
1111 - 0101 = 1111 + 1010 + 1 = 11010
1110 = 0101 = 1110 + 1010 + 1 = 11001

这就解决了这个问题。

有符号溢出被定义为进位不等于加法器的msbit上的进位。这可能会变得混乱,所以我们只需要知道边界在哪里。

0111 - 0101 = 7 - 5 = 2
0110 - 0101 = 6 - 5 = 1
0101 - 0101 = 5 - 5 = 0
0100 - 0101 = 4 - 5 = -1
0011 - 0101 = 3 - 5 = -2

等等。使用这个4位模型,在带符号的解释中,我们被限制在+7(0b0111)到-8(0b1000)。所以在-3到5之后我们会遇到麻烦:

1110 - 0101 = 1110 + 1010 + 1 = 11001 , -2 - 5 = -7
1101 - 0101 = 1101 + 1010 + 1 = 11000 , -3 - 5 = -8
1100 - 0101 = 1100 + 1010 + 1 = 10111 , -4 - 5 = 7 (-9 if we had more bits)
1011 - 0101 = 1011 + 1010 + 1 = 10110 , -5 - 5 = 6 (-10 if we had more bits)
1010 - 0101 = 1010 + 1010 + 1 = 10101 , -6 - 5 = 5 (-11 if we had more bits)
1001 - 0101 = 1001 + 1010 + 1 = 10100 , -7 - 5 = 4 (-12 if we had more bits)
1000 - 0101 = 1000 + 1010 + 1 = 10011 , -8 - 5 = 3 (-13 if we had more bits)

后五个是有符号溢出,签名结果无法用可用位数表示。 (记住我们现在正在玩一个四位系统,最高位是进位,当你查看结果时可以直观地删除它。)

签名标志只是结果的msbit,它也改变了有趣的边界。设置有符号标志(结果的msbit)的情况是低于5的正(eax)值和不导致有符号溢出(+4低至-3)的负数。所有这些都在< 5类别中,因此他们希望得到2的结果。第一个测试查找设置了符号的情况,为什么它会麻烦然后测试签名溢出?这没有任何意义,我们已经知道所有签署的结果都在不到5个类别中。如果签名溢出没有伤害额外的跳跃。

所以,如果你通过js登录,那么符号位是关闭的,这是大于或等于5的数字(想要结果为1)或结果为负,导致有符号溢出(想要结果为2)。所以jo elseblock通过拾取2个案例的结果来排除这两个案例(签名溢出,非常消极)。并且jmp thenblock将正数高于5。

在我看来,你在这里正在进行签名数学运算(使用带符号的溢出标志有点明显)。由于您使用5来比较和签名数学,您需要在系统中使用4位或更多位来实现此代码,因此8,32,64,123456位,无关紧要,它与4位系统的工作方式相同(对于这个比较)。我发现更容易最小化进行分析的位数。像这样的硬编码比较使得它更容易,因为上面的计算结果只是在上面,下面和下面。然后遍历全零(零)到全部(减1)用于有符号数,并且在签名溢出范围内非常负。对于无符号数字,它更容易但过程相同。

答案 1 :(得分:0)

if(EAX> = 5)   EBX = 1; 其他   EBX = 2;“

cmp eax,5
jae biggerthan
mov ebx,2
jmp out
.biggerthan
mov ebx,1
.out
相关问题