【发布时间】:2017-12-28 20:50:18
【问题描述】:
我正在阅读 Jeff Duntemann 的Assembly Language Step-by-Step,我对某些条件跳转的工作原理感到困惑。我知道CMP 用于使用减法比较两个值,然后丢弃结果以设置标志。
有什么方法可以确定需要设置/取消设置哪些标志?我了解JE 和JNE 会查看是否设置了ZF,但我不确定其他分支操作。
这是我坚持的部分:
ClearLine:
pushad ; Save all caller’s GP registers
mov edx,15 ; We’re going to go 16 pokes, counting from 0
.poke: mov eax,1
sub edx,1
jae .poke ; Loop back if EDX >= 0
popad
ret `
如果 EDX >= 0,为什么JAE 会循环返回?如果 EDX >= 1,它不会循环吗?毕竟,SUB 操作就像CMP 操作一样,但多了一个保存结果的步骤。所以基本上说CMP edx,1不是说“如果第一个操作数(EDX)大于或等于第二个操作数(1)则跳转”?但是当我在调试器中测试它时,它显示它循环了 16 次,而不是 15 次。我不明白为什么会这样。
【问题讨论】:
-
是的,你是对的。您可以在调试器中对其进行测试。另外,
jae是一个无符号比较,所以>= 0没有意义,对于所有无符号数字都是如此。 -
当 edx=1 时,
sub会做:edx = 0, ZF=1, CF=0。所以jae将循环到.poke。当edx=0时,sub会导致edx=0xFFFFFFFF,ZF=0,CF=1,即“jnae”或“jb”,所以会跳过jae。所以 jae 确实将 edx 值(在 sub 之前)从 15 跳回到 1 => 15 次 => +1 非跳转(edx=0 在 sub 之前)=> 循环将执行 16 次。 -
如果它引用了在减法之后的值,则该语句是有意义的。如果 edx 在
sub之前为 1,则之后将为 0,但“比较”使用之前的值。使用do { ... } while(edx-- >= 1)的 C 语法(注意后增量) -
如果仍然不确定...做
mov edx,0=> 循环将被执行1次。mov edx,1=> 2 次,等等...因为它是do { ... } while(...);类型的循环,而不是for(..) {},它将首先测试edx是否应该至少第一次执行循环。 -
那么当使用跳转指令时,我怎么知道它和什么比较呢?
标签: assembly x86 conditional-statements branch