Lab 3: Control Structure
Table of Contents
Overview
Control structures (branches and loops) are necessary in programming.
You will learn how to make if/else blocks and loops.
Note
These examples use labels that are familiar for control statements. Your program should not these types of labels. Your should use descriptive labels that describe the purpose of the block.
These types of labels will not be accepted:
loop
end_if
zzzzzz
asdf
does_something
Sources
- NASM Control Structures (Module) - University of Hawaii 
- Jumps and Branches - University of Hawaii Presentation 
- Control Structures - University of Hawaii Presentation 
- Conditionals: Goto and Branch Instructions - University of Alaska 
Branches
Branches, go statements, or jumps usually happen after a comparison or operation that can set a flag on the processor.
They are the conditional version of the unconditional jmp command.
mov eax, 100 jmp next ; jump to next ; skip these commands add eax, ecx next: ; do something here
Branch on State of Flag
| Instruction | Condition | Info | 
|---|---|---|
| JZ | Zero flag:  | mov  edx, 5
mov  ecx, 5
sub  ecx, edx
; jump if result == 0
jz   zero_value
 | 
| JNZ | Zero flag:  | mov  ebx, 5
cmp  ebx, 0
; jump if ebx != 0
jnz   value_not_zero
 | 
| JO | Signed overflow:  | mov  ebx, 2147483647
add  ebx, 1
jo  overflow_detected
; FLAGS = 0A96 OF    SF    AF PF
 | 
| JNO | Signed overflow:  | mov  ebx, 2147483647
sub  ebx, 1
jno  no_overflow_detected
; FLAGS = 0202
 | 
| JS | Sign flag:  | mov  ebx, 0
sub  ebx, 10
js  negative_value
; FLAGS = 0297       SF    AF PF CF
 | 
| JNS | Sign flag:  | mov  ebx, 10
sub  ebx, 10
jns  not_negative
; FLAGS = 0246          ZF    PF
 | 
| JC | Unsigned Carry flag  | mov  eax, 4294967294
add  eax, 2
jc   handle_unsigned_carry
; FLAGS = 0257          ZF AF PF CF
 | 
| JNC | Unsigned Carry flag  | mov  eax, 4294967294
add  eax, 1
jnc  no_unsigned_carry
;FLAGS = 0286       SF       PF
 | 
Branches for Equality Tests
This group is a result of command cmp.
cmp eax, ecx ; compare and then evaluate
| Instruction | Condition | Info | 
|---|---|---|
| JE | Jump if  | mov  eax, 10
mov  ecx, 10
cmp  eax, ecx
; jump if eax == ecx
je   match_found
 | 
| JNE | Jump if  | mov  eax, 5
mov  ecx, 10
cmp  eax, ecx
; jump if eax != ecx
jne  not_equal
 | 
| JG | Signed   | greater than | 
| JGE | Signed   | greater than or equals | 
| JL | Signed   | less than | 
| JLE | Signed   | less than or equals | 
| JA | Unsigned  | above | 
| JAE | Unsigned  | above or equals | 
| JB | Unsigned   | below | 
| JBE | Unsigned   | below or equals | 
Consider the following C-like code wither register-like variables
if (EAX == 0) EBX = 1; else EBX = 2;
Here it is in x86 assembly. Notice the jz flag.
cmp eax, 0 ; do the comparison jz then_block ; if = 0, then goto then_block mov ebx, 2 ; else clause jmp next ; jump over the then clause then_block: mov ebx, 1 ; then clause next: ; continue the program
Control Block Examples
If-Else block
View runnable file: if-then.asm.txt
if statementif (condition) then
    then_block
if statement    ; instructions to set flags (e.g., cmp ...)
    jXX  end_if         ; evaluate flag. Jump on true condition
    ; then_block code
end_if:
    ; program continues
If-Then-Else block
View runnable file: if-then-else.asm.txt
if-then-else statementif (condition) then
    then_block
else
    else_block
if-then-else statement    ; instructions to set flags (e.g., cmp ...)
    jXX    else_block       ; evaluate flag. Jump on true condition
    ; then_block code
    jmp end_if              ; skip the else_block
else_block:
    ; code for the else block
end_if:
    ; program continues
For loops
There are two variants of the for loop. The first is a
traditional approach incrementing i. The second option
uses the loop command, which operates in reverse order.
Traditional for loop
View runnable file: for.asm.txt
for loopsum = 0;
for (i = 0; i <= 10; i++) {
    sum += i;
}
for loop    mov    eax,  0          ; eax is sum
    mov    ebx,  0          ; ebx is i (could be ecx or edx)
loop_start:
    cmp    ebx,  10         ; compare i and 10
    jg     loop_end         ; if (i > 10) goto loop_end
    add    eax, ebx         ; sum += i
    inc    ebx              ; i++
    jmp    loop_start       ; goto loop_start
loop_end:
    ; program continues
loop command (Reverse loop)
View runnable file: loop.asm.txt
for loopsum = 0;
for (i = 10; i > 0; i--) {
    sum += i;
}
for loop    mov    eax, 0          ; eax is the sum
    mov    ecx, 10         ; ecx is i (this must be ECX)
loop_start:
    add    eax, ecx        ; sum += i
    loop   loop_start      ; if i > 0 then  go to loop_start
    ; program continues when ECX == 0
While loop
View runnable file: while.asm.txt
while loopwhile (condition) {
   body
}
while loopwhile:
    ; instructions to set flags (e.g., cmp...)
    jXX    end_while        ; evaluate flag. Jump on true condition
    ; body of loop
    jmp    while            ; continue loop
end_while:
    ; program continues
Do-While loop
View runnable file: do-while.asm.txt
do {
   body
} while (condition)
do:
    ; body of loop
    ; instructions to set flags (e.g., cmp...)
    jXX    do                  ; evaluate flag. Jump on true condition
    ; program continues
Task 1: If Statement
You are performing system upgrades. However, not all systems will receive the upgrade at the same time. You need to write code to prevent a system crash and to protect data from an overflow.
Your task is to create a NASM program that squares a number to determine if it will fit in the current register. If not, print the original value. The program must work with any register size (16, 32, or 64 bit).
int value = 8192;
if (can_square)
    value = value * value;
printf(value);
See the Lab 3.1 Solutions if you need help.
Task 2: If/Else Statement
Your task is to create a NASM program that determines if a number is even or odd. Print 0 for even numbers and 1 for odd numbers.
int value = 8192;
if (even)
    value = 0;
else
    value = 1;
printf(value);
See the Lab 3.2 Solutions if you need help.
Task 3: While Loop
You need to track the number of cycles that an operation takes to complete. Create a while loop that performs some action. Print the number of loop iterations.
You could evaluate a zero value (ZF), less than, or greater than
int counter = 0;
// Example using greater than
while (value <! maximum) {
   value = value + 10;
   counter ++;
}
printf(counter);
See the Lab 3.3 Solutions if you need help.
Task 4: Factorial
Use the ASM implementation of a for loop to calculate the factorial
of a number. See C programming lab 1 for additional
information.
int i;                           // ECX
int factorial = 5;               // EBX
int result = 1;                  // EAX
for (i = 1; i <= factorial; i++)
{
    result = result * i;
    // Check for overflow. -1 will indicate that an error occurred.
    if (OVERFLOW_FLAG) {
        factorial = 0;          // loop condition
        result = -1;            // set to -1 (invalid factorial)
        print(i);               // Record max factorial number + 1
    }
    // Optionally, print the incremental number to help you debug
    // printf(result);
}
printf(result);
; 5!
120
; 12!
479001600
; 18! (n! > 12)
13          ; 13! caused an overflow
-1          ; error
See the Lab 3.4 Solutions if you need help.