assembly 汇编x86 - jnz指令

bqujaahr  于 2022-12-19  发布在  其他
关注(0)|答案(2)|浏览(294)

我了解到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
qvtsj1bj

qvtsj1bj1#

让我们看看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中,放置在循环末尾并跳回到循环顶部的条件测试是说什么时候继续循环,而不是什么时候停止循环。

zxlwwiss

zxlwwiss2#

jnz指令的意思是“如果没有设置z标志,就跳转”。当dx为4,并且你把它与0进行比较时,z标志不会被设置,所以跳转就发生了。所以它与==比较不同,它是!=比较。
注意,在最初的Intel汇编程序中,JNZ也可以写成JNE;都是同样的机器指令。

相关问题