X86 Disassembly/Loops

Loops
To complete repetitive tasks, programmers often implement loops. There are many sorts of loops, but they can all be boiled down to a few similar formats in assembly code. This chapter will discuss loops, how to identify them, and how to "decompile" them back into high-level representations.

Do-While Loops
It seems counterintuitive that this section will consider Do-While loops first, considering that they might be the least used of all the variations in practice. However, there is method to our madness, so read on.

Consider the following generic Do-While loop:

What does this loop do? The loop body simply executes, the condition is tested at the end of the loop, and the loop jumps back to the beginning of the loop if the condition is satisfied. Unlike if statements, Do-While conditions are not reversed.

Let us now take a look at the following C code:

Which can be translated into assembly language as such:

While Loops
While loops look almost as simple as a Do-While loop, but in reality they aren't as simple at all. Let's examine a generic while-loop:

What does this loop do? First, the loop checks to make sure that x is true. If x is not true, the loop is skipped. The loop body is then executed, followed by another check: is x still true? If x is still true, execution jumps back to the top of the loop, and execution continues. Keep in mind that there needs to be a jump at the bottom of the loop (to get back up to the top), but it makes no sense to jump back to the top, retest the conditional, and then jump back to the bottom of the loop if the conditional is found to be false. The while-loop then, performs the following steps:


 * 1) check the condition. if it is false, go to the end
 * 2) perform the loop body
 * 3) check the condition, if it is true, jump to 2.
 * 4) if the condition is not true, fall-through the end of the loop.

Here is a while-loop in C code:

And here then is that same loop translated into assembly:

If we were to translate that assembly code back into C, we would get the following code:

See why we covered the Do-While loop first? Because the While-loop becomes a Do-While when it gets assembled.

So why can't the jump label occur before the test?

For Loops
What is a For-Loop? In essence, it's a While-Loop with an initial state, a condition, and an iterative instruction. For instance, the following generic For-Loop:

gets translated into the following pseudocode while-loop:

Which in turn gets translated into the following Do-While Loop:

Note that often in for loops you assign an initial constant value in A (for example x = 0), and then compare that value with another constant in B (for example x < 10). Most optimizing compilers will be able to notice that the first time x IS less than 10, and therefore there is no need for the initial if(B) statement. In such cases, the compiler will simply generate the following sequence:

rendering the code indistinguishable from a while loop.

Other Loop Types
C only has Do-While, While, and For Loops, but some other languages may very well implement their own types. Also, a good C-Programmer could easily "home brew" a new type of loop using a series of good macros, so they bear some consideration:

Do-Until Loop
A common Do-Until Loop will take the following form:

which essentially becomes the following Do-While loop:

Until Loop
Like the Do-Until loop, the standard Until-Loop looks like the following:

which (likewise) gets translated to the following While-Loop:

Do-Forever Loop
A Do-Forever loop is simply an unqualified loop with a condition that is always true. For instance, the following pseudo-code:

will become the following while-loop:

Which can actually be reduced to a simple unconditional jump statement:

Notice that some non-optimizing compilers will produce nonsensical code for this:

Notice that a lot of the comparisons here are not needed since the condition is a constant. Most compilers will optimize cases like this.