如何阅读这个x86程序集“for”循环

时间:2017-01-20 06:22:46

标签: for-loop assembly

CheckIfStop:
   cmp eax, 5
   jnl End

书中的翻译说“如果eax不小于(大于或等于)5的值,则会采取条件跳转。”

为什么它不能被读取(相反)为“...如果5不小于(大于或等于)eax的值?我没有看到如何阅读jnl与值eax和5之间的关联。

参考状态,cmp是Op1-Op2。

谢谢!

2 个答案:

答案 0 :(得分:2)

大多数指令不对称:or eax, ebx读取两个寄存器但仅设置eax 因此cmp同样如此并不奇怪:第一个操作数是与第二个操作数相比较的操作数和jcc指令族进行的条件检查的主题。

cmp eax, 5读取比较EAX与5 jnl End读取如果不小于那么跳转到结束

考虑cmp作为主题的第一个来源的技巧效果很好,但如果它有时会失败,我不会感到惊讶。
请记住,cmp只是sub,它会丢弃结果,但仍设置标记,稍后使用jcc指令进行测试。

减法不是可交换的,因此cmp eax, ebxcmp ebx, eax有两种不同的语义:两者都比较EAX和EBX,但第一种是从EAX的角度来看(所以ja会测试EAX&gt ; EBX)和后者从EBX的角度来看(所以ja将测试EBX> EAX)。

答案 1 :(得分:0)

CMP的说明是:

  

比较第一个源操作数和第二个源操作数,并设置EFLAGS寄存器中的状态标志   根据结果​​。通过从第一个操作数中减去第二个操作数来执行比较   然后以与SUB指令相同的方式设置状态标志。

因此,在您的情况下,根据eax-5设置标志。

JNL表示“跳转,如果SF == OF”(其中SF是符号标志,OF是溢出标志)。< / p>

我们如何最终得到SF == OF?好吧,SF非常明显,如果减法的结果为负,则会设置,否则将被清除。

OF将在以下任何一种情况下设置为减法:

  • 正Op1 - 负Op2 =负结果
  • 负Op1 - 正Op2 =正结果

因此,我们可以得到SF = 1且OF = 1的唯一情况是,正Op1和负Op2产生负面结果。显然5不是负面的,所以这不符合你提出的描述。

让我们看看SF = 0和OF = 0。在以下情况下可能会发生这种情况:

  • 正Op1 - 正Op2 =正结果
  • 正Op1 - 负Op2 =正结果
  • 负Op1 - 负Op2 =正结果

Op2 = 5中唯一适合的是第一个。但是那个也需要一个正的Op1和一个正的结果,这只有在Op1大于或等于Op2时才会发生,即如果5小于或等于Op1。