The approach I recommend for understanding control flow and how to implement structured statement in assembly is to use the if-goto-label construct that some languages, like C, have. This approach is fairly universal across assembly languages, and it goes like this:
We have labels, which do not execute, but can be targets of branches. We also have unconditional branches, in C, the goto label;
statement. We also have conditional branches, which in C are composed of an if and a goto as follows: if ( ... ) goto label;
An if-then-else statement has a pattern in high level language:
if ( <condition> ) {
<then-part>
}
else {
<else-part>
}
This same pattern using if-goto-label goes like this:
if ( ! <condition> ) goto else1;
<then-part>
goto endIf1;
else1:
<else-part>
endIf1:
The condition needs to be negated or reversed, since in assembly language we tell the processor when to skip the then-part and execute the else-part whereas with an if-then-else the condition is for when to fire the then-part.
In assembly you'll want control structures just like the if-goto-label form I'm showing above. Remember that labels don't execute or change the behavior of the processor (it actually doesn't even see labels, they are removed by the assembler).
For a nested if statement, we simply follow the pattern translation. Each individual if-statement needs its own labels, which is why I number them: if1/then1/else1/endif1, if2/then2/else2/endif2...
In assembly language the unconditinoal branch (C's goto label;
) is just jmp
, and conditional branches are compare followed by conditional branch like jle
(jump if signed less-than-or-equal or je
(jump if equal).