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
CodePudding user response:
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.
CodePudding user response:
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 (i.e. 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 negation the condition between C and assembly.
If we were using Pascal's repeat-until (whose condition sense is opposite C's do-while), which says when to stop the loop, 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.