汇编jnz指令



我了解到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;这是相同的机器指令。

最新更新