我了解到jnz
意味着我们可以在c中翻译为if (x==y)
。对于下面的代码,在循环中进行操作后,我们得到dx等于4。它不等于0但是while循环继续-为什么?
mov ax, 1024
mov cx, 0
moc bx, 10
wh: mov dx, 0
div bx
add cx, 1
cmp dx, 0
jnz wh
让我们看一下c语言中的while循环。
while ( condition ) {
<loop-body>
}
while
循环的C语义表示何时保持(即继续)循环。
为了将其翻译成汇编语言的if-goto-label风格,我们将告诉处理器何时退出循环,而不是何时留在循环中(还有其他选项,但这是最直接的翻译)。
loop1:
if ( ! condition) goto loop1End;
<loop-body>
goto loop1;
loop1End:
因此,条件被否定了,因为我们告诉处理器何时退出,而不是告诉C何时继续(恰恰相反)。
然而,您所展示的代码具有do-while循环的语义-并且在C和汇编中,do-while循环表示何时继续,何时返回顶部的条件,而不是何时退出。因此,不需要对C和汇编之间的条件取反。
do {
<loop-body>
} while ( condition );
程序集的if-goto-label样式:
loop1:
<loop-body>
if ( condition ) goto loop1;
是否反转条件取决于上下文。
在汇编中,while
循环的顶部条件分支以底部的退出标签为目标(正向分支),而do-while
循环的底部条件分支以顶部的循环标签为目标(向后分支)。
因此,我们必须知道:我们是要求处理器退出循环(向前分支)还是继续循环(向后分支),C也是如此(我们说什么时候继续或什么时候停止)-如果语义相反,那么我们必须否定C和汇编之间的条件。
在Pascal的repeat-until结构中,条件测试位于循环的末尾,表示何时退出循环。为了将其转换为C,我们将使用do-while,尽管do-while具有相反的含义(何时继续),我们也将在Pascal和C之间转换时否定条件,反之亦然。因此,这不是汇编语言独有的情况。
如果使用Pascal的repeat-until,则必须反转汇编等价的条件,因为在汇编的If -goto-label中,放置在循环末尾并跳转到循环顶部的条件测试表示何时继续循环,而不是何时停止循环。
jnz指令表示"如果未设置z标志,则跳转"。当dx为4时,你将它与0进行比较,z标志将不会被设置,因此进行了跳转。所以它和==比较不同,它是!=比较。
注意,在原始的Intel汇编程序中,JNZ
也可以写成JNE
;这是相同的机器指令。