The Art of
ASSEMBLY LANGUAGE PROGRAMMING

Chapter Nine

Table of Content

Chapter Ten (Part 2)

CHAPTER TEN:
CONTROL STRUCTURES (Part 1)
10.0 - Chapter Overview
10.1 - Introduction to Decisions
10.2 - IF..THEN..ELSE Sequences
10.3 - CASE Statements
10.4 - State Machines and Indirect Jumps
10.5 - Spaghetti Code
10.6 - Loops
10.6.1 - While Loops
10.6.2 - Repeat..Until Loops
10.6.3 - LOOP..ENDLOOP Loops
10.6.4 - FOR Loops
10.7 - Register Usage and Loops
10.8 - Performance Improvements
10.8.1 - Moving the Termination Condition to the End of a Loop
10.8.2 - Executing the Loop Backwards
10.8.3 - Loop Invariant Computations
10.8.4 - Unraveling Loops
10.8.5 - Induction Variables
10.8.6 - Other Performance Improvements
10.9 - Nested Statements
10.10 - Timing Delay Loops
10.11 - Sample Program
Copyright 1996 by Randall Hyde All rights reserved.

Duplication other than for immediate display through a browser is prohibited by U.S. Copyright Law.
This material is provided on-line as a beta-test of this text. It is for the personal use of the reader only. If you are interested in using this material as part of a course please contact rhyde@cs.ucr.edu

Supporting software and other materials are available via anonymous ftp from ftp.cs.ucr.edu. See the "/pub/pc/ibmpcdir" directory for details. You may also download the material from "Randall Hyde's Assembly Language Page" at URL: http://webster.ucr.edu

Notes:
This document does not contain the laboratory exercises programming assignments exercises or chapter summary. These portions were omitted for several reasons: either they wouldn't format properly they contained hyperlinks that were too much work to resolve they were under constant revision or they were not included for security reasons. Such omission should have very little impact on the reader interested in learning this material or evaluating this document.

This document was prepared using Harlequin's Web Maker 2.2 and Quadralay's Webworks Publisher. Since HTML does not support the rich formatting options available in Framemaker this document is only an approximation of the actual chapter from the textbook.

If you are absolutely dying to get your hands on a version other than HTML you might consider having the UCR Printing a Reprographics Department run you off a copy on their Xerox machines. For details please read the following EMAIL message I received from the Printing and Reprographics Department:

Hello Again Professor Hyde

Dallas gave me permission to take orders for the Computer Science 13 Manuals. We would need to take charge card orders. The only cards we take are: Master Card Visa and Discover. They would need to send the name numbers expiration date type of card and authorization to charge $95.00 for the manual and shipping also we should have their phone number in case the company has any trouble delivery. They can use my e-mail address for the orders and I will process them as soon as possible. I would assume that two weeks would be sufficient for printing packages and delivery time.

I am open to suggestions if you can think of any to make this as easy as possible.

Thank You for your business
Kathy Chapman Assistant
Printing and Reprographics University of California Riverside (909) 787-4443/4444

We are currently working on ways to publish this text in a form other than HTML (e.g. Postscript PDF Frameviewer hard copy etc.). This however is a low-priority project. Please do not contact Randall Hyde concerning this effort. When something happens an announcement will appear on "Randall Hyde's Assembly Language Page." Please visit this WEB site at http://webster.ucr.edu for the latest scoop.

Redesigned 10/2000 with "MS FrontPage 98" using 17" monitor 1024x768
(c) 2000 BIRCOM Entertainment'95


A computer program typically contains three structures: instruction sequences decisions and loops. A sequence is a set of sequentially executing instructions. A decision is a branch (goto) within a program based upon some condition. A loop is a sequence of instructions that will be repeatedly executed based on some condition. In this chapter we will explore some of the common decision structures in 80x86 assembly language.

10.0 Chapter Overview

This chapter discusses the two primary types of control structures: decision and iteration. It describes how to convert high level language statements like if..then..else case (switch) while for etc. into equivalent assembly language sequences. This chapter also discusses techniques you can use to improve the performance of these control structures. The sections below that have a "*" prefix are essential. Those sections with a "o" discuss advanced topics that you may want to put off for a while.

* Introduction to Decisions.

* IF..THEN..ELSE Sequences.

* CASE Statements.

    o State machines and indirect jumps.

* Spaghetti code.

* Loops.

* WHILE Loops.

* REPEAT..UNTIL loops.

* LOOP..ENDLOOP.

* FOR Loops.

* Register usage and loops.

    o Performance improvements.

    o Moving the termination condition to the end of a loop.

    o Executing the loop backwards.

    o Loop invariants.

    o Unraveling loops.

    o Induction variables.

10.1 Introduction to Decisions

In its most basic form a decision is some sort of branch within the code that switches between two possible execution paths based on some condition. Normally (though not always) conditional instruction sequences are implemented with the conditional jump instructions. Conditional instructions correspond to the if..then..else statement in Pascal:

 	IF (condition is true) THEN stmt1 ELSE stmt2 ;

Assembly language as usual offers much more flexibility when dealing with conditional statements. Consider the following Pascal statement:

 	IF ((X<Y) and (Z > T)) or (A <> B) THEN stmt1;

A "brute force" approach to converting this statement into assembly language might produce:

                mov     cl
1           ;Assume true
mov     ax
X
cmp     ax
Y
jl      IsTrue
mov     cl
0           ;This one's false
IsTrue:         mov     ax
Z
cmp     ax
T
jg      AndTrue
mov     cl
0           ;It's false now
AndTrue:        mov     al
A
cmp     al
B
je      OrFalse
mov     cl
1           ;Its true if A <> B
OrFalse:        cmp     cl
1
jne     SkipStmt1
<Code for stmt1 goes here>
SkipStmt1:

As you can see it takes a considerable number of conditional statements just to process the expression in the example above. This roughly corresponds to the (equivalent) Pascal statements:

                cl := true;
IF (X >= Y) then cl := false;
IF (Z <= T) then cl := false;
IF (A <> B) THEN cl := true;
IF (CL = true) then stmt1;

Now compare this with the following "improved" code:

                mov     ax
A
cmp     ax
B
jne     DoStmt
mov     ax
X
cmp     ax
Y
jnl     SkipStmt
mov     ax
Z
cmp     ax
T
jng     SkipStmt
DoStmt:
<Place code for Stmt1 here>

SkipStmt:

Two things should be apparent from the code sequences above: first a single conditional statement in Pascal may require several conditional jumps in assembly language; second organization of complex expressions in a conditional sequence can affect the efficiency of the code. Therefore care should be exercised when dealing with conditional sequences in assembly language.

Conditional statements may be broken down into three basic categories: if..then..else statements case statements and indirect jumps. The following sections will describe these program structures how to use them and how to write them in assembly language.

10.2 IF..THEN..ELSE Sequences

The most commonly used conditional statement is theif..then or if..then..else statement. These two statements take the following form shown below:

The if..then statement is just a special case of the if..then..else statement (with an empty ELSE block). Therefore we'll only consider the more general if..then..else form. The basic implementation of an if..then..else statement in 80x86 assembly language looks something like this:

        {Sequence of statements to test some condition}
Jcc     ElseCode
{Sequence of statements corresponding to the THEN block}
jmp     EndOfIF

ElseCode:
{Sequence of statements corresponding to the ELSE block}

EndOfIF:

Note: Jcc represents some conditional jump instruction.

For example to convert the Pascal statement:

	IF (a=b) then c := d else b := b + 1;

to assembly language you could use the following 80x86 code:

                mov     ax
a
cmp     ax
b
jne     ElseBlk
mov     ax
d
mov     c
ax
jmp     EndOfIf

ElseBlk:
inc     b
EndOfIf: 

For simple expressions like (A=B) generating the proper code for an if..then..else statement is almost trivial. Should the expression become more complex the associated assembly language code complexity increases as well. Consider the following if statement presented earlier:

	IF ((X > Y) and (Z < T)) or (A<>B) THEN C := D;

When processing complex if statements such as this one you'll find the conversion task easier if you break this if statement into a sequence of three different if statements as follows:

	IF (A<>B) THEN C := D
IF (X > Y) THEN   IF (Z < T) THEN C := D;

This conversion comes from the following Pascal equivalences:

	IF (expr1 AND expr2) THEN stmt;

is equivalent to

	IF (expr1) THEN IF (expr2) THEN stmt;

and

	IF (expr1 OR expr2) THEN stmt;

is equivalent to

	IF (expr1) THEN stmt;
IF (expr2) THEN stmt;

In assembly language the former if statement becomes:

                mov     ax
A
cmp     ax
B
jne     DoIF
mov     ax
X
cmp     ax
Y
jng     EndOfIf
mov     ax
Z
cmp     ax
T
jnl     EndOfIf
DoIf:
mov     ax
D
mov     C
ax
EndOfIF:

As you can probably tell the code necessary to test a condition can easily become more complex than the statements appearing in the else and then blocks. Although it seems somewhat paradoxical that it may take more effort to test a condition than to act upon the results of that condition it happens all the time. Therefore you should be prepared for this situation.

Probably the biggest problem with the implementation of complex conditional statements in assembly language is trying to figure out what you've done after you've written the code. Probably the biggest advantage high level languages offer over assembly language is that expressions are much easier to read and comprehend in a high level language. The HLL version is self-documenting whereas assembly language tends to hide the true nature of the code. Therefore well-written comments are an essential ingredient to assembly language implementations of if..then..else statements. An elegant implementation of the example above is:

; IF ((X > Y) AND (Z < T)) OR (A <> B) THEN C := D;
; Implemented as:
; IF (A <> B) THEN GOTO DoIF;

mov     ax
A
cmp     ax
B
jne     DoIF

; IF NOT (X > Y) THEN GOTO EndOfIF;

mov     ax
X
cmp     ax
Y
jng     EndOfIf

; IF NOT (Z < T) THEN GOTO EndOfIF ;

mov     ax
Z
cmp     ax
T
jnl     EndOfIf

; THEN Block:

DoIf:           mov     ax
D
mov     C
ax

; End of IF statement

EndOfIF: 

Admittedly this appears to be going overboard for such a simple example. The following would probably suffice:

; IF ((X > Y) AND (Z < T)) OR (A <> B) THEN C := D;

; Test the boolean expression:

mov     ax
A
cmp     ax
B
jne     DoIF
mov     ax
X
cmp     ax
Y
jng     EndOfIf
mov     ax
Z
cmp     ax
T
jnl     EndOfIf

; THEN Block:

DoIf:           mov     ax
D
mov     C
ax

; End of IF statement

EndOfIF: 

However as your if statements become complex the density (and quality) of your comments become more and more important.

Chapter Nine

Table of Content

Chapter Ten (Part 2)

Chapter Ten: Control Structures (Part 1)
27 SEP 1996