简体   繁体   中英

Assembly x86 - jnz instruction

I learnt that jnz means what we could translate as if (x==y) in C. In case of the code below, after doing the operations in the loop, we have dx equal to 4. It's not equal to 0 but the while loop is conitnued - why is that?

     mov ax, 1024
     mov cx, 0
     moc bx, 10
wh:  mov dx, 0
     div bx
     add cx, 1
     cmp dx, 0
     jnz wh

Let's look at a while loop in C.

while ( condition ) {
    <loop-body>
}

The C semantics of a while loop say when to stay in (ie continue) the loop.

In order to translate this into assembly language's if-goto-label style, we would tell the processor when to exit the loop rather than when to stay in the loop (there are other options, but this is the most direct translation).

loop1:
    if ( ! condition) goto loop1End;
    <loop-body>
    goto loop1;
loop1End:

So, the condition is negated since we're telling the processor when to exit rather than telling C when to continue (the exact opposite).

However, the code you're showing has the semantics of a do-while loop — and in both C an assembly, a do-while loop expresses the condition with when to continue, when to go back to the top, rather than when to exit. So, there is no need for negating the condition between C and assembly.

do {
    <loop-body>
} while ( condition );

in assembly's if-goto-label style:

loop1:
    <loop-body>
    if ( condition ) goto loop1;

Whether or not to reverse the condition depends on context.

In assembly, the while loop's conditional branch at the top targets the exit label (forward branch) at the bottom, whereas the do-while loops conditional branch at the bottom targets the loop label at the top (backward branch).

So, we have to know: are we asking the processor to exit the loop (forward branch) or continue the loop (backward branch), and the same with C (are we saying when to continue or when to stop) — if the semantics are opposite then we must negate the condition between C and assembly.


In Pascal's repeat-until construct, the condition test is at the end of the loop and says when to exit the loop. To translate that to C we would use a do-while, though since do-while has the opposite sense (when to continue), we would also negate the condition in translation between Pascal and C and vice versa. So, this is not a situation unique to assembly language alone.

If we were using Pascal's repeat-until, we would have to reverse the condition for assembly equivalent, since in assembly's if-goto-label, a condition test placed at the end of the loop that jumps back to the top of the loop is saying when to continue the loop rather than when to stop the loop.

The jnz instruction means "jump if the z flag is not set". When dx is 4, and you compare it to 0, the z flag will not be set, so the jump is made. So it's not the same as an == comparison, it's a.= comparison.

Note that in the original Intel assembler, JNZ could also be written as JNE ; it's the same machine instruction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM