next up previous
Next:Lesson 9 Up: Overview Previous: Lesson 2


Lesson 3

Lesson 3: Conditions

Like last time, begin by mentioning the new instructions that will be introduced, JMP, CMP, COND.

Performing calculations and conversations are important skills, but to make truely useful programs we need to be able to carry out entirely different behavior routines depending upon certain conditions. We use what are called conditionals in order to do so, these allow us to jump to different braches of our code, instead of only executing sequentially.

However, before we get to them, we need to a few more tools. First, we'll be introduced to a 'note'.

    MOV    AX,1
    ; this line is a note, and does nothing
    MOV    BX,2

Notes begin with a semicolon, and then can have any text at all until the end of the line. This line is then ignored, performing no calculations or modifications to the machine state. Notes are useful for providing information to anyone reading the code, helping them to understand it in simple written English.

Although a note does not perform any actions, it still can have an effect on code. A note may identify some section of a program, allowing us to directly refer to sections of code later on. For example:

    ; rudely demand a number
    POINT  AX,"Give me a number!"
    OUTPUT TEXT
    ;gavePrompt
    INPUT
    ;done

Here we can use gavePrompt to refer to the point of execution between OUTPUT TEXT and INPUT, and done to refer to the tail end of the program. This is useful for certain instructions, such as JMP, which allows us to change the point of execution to any place referenced with a note.

    MOV    AX,1
    JMP    skipThirdLine
    MOV    AX,2
    ;skipThirdLine
    OUTPUT

This above code section will output the number 1. When the second instruction is reached, execution moves to after the note ;skipThirdLine. The third line of code never gets run, so AX still retains the value 1.

To see this another way, let's look at the states corresponding to this code chunk. Notice that MOV AX,2 never gets run.

    -----------------------------
    State  AX  Next instruction
    0      ?   MOV AX,1
    1      1   JMP skipThirdLine
    2      1   OUTPUT
    3      1   -
    -----------------------------

Unforunately, JMP only allows us change the execution order unconditionally. The branching always occurs no matter what. In order to have a variety of behaviors, we need some way to change execution order based upon some condition.

The CMP and COND instructions are useful here. CMP compares two values. COND is similar to JMP, but only branches if the CMP before it finds its two values to be the same. The following requirement will demonstrate how to use these instructions.

    Have the user input a number. If that value is one, do nothing, otherwise print 'not one'

Here it should be clear that we'll need to use a conditional in order to choose what behavior to follow. First we can use the CMP instruction to perform a comparision, and then use COND to pick what to do.

    INPUT
    CMP    AX,1
    COND   done
    POINT  AX,"not one"
    OUTPUT TEXT
    ; done

Even though JMP is unconditional, it is still very useful. For example, if we want to perform two entirely different sets of behaviors, we can combine CMP/COND with JMP in order to do so.

    Have the user input a number. If that value is one, print 'one', otherwise print 'not one'

Here we'll employ CMP/COND in order to avoid executing the first branch, and at the end of that branch, use JMP to skip the second branch, like so

    INPUT
    CMP    AX,1
    COND   passes
    POINT  AX,"not one"
    OUTPUT TEXT
    JMP    done
    ; passes
    POINT  AX,"one"
    OUTPUT TEXT
    ; done

This structure is known as if/then/else, and is a very powerful construct. We'll see it come up again and again. Let's see how it works by using a state table, once for when 1 is inputted, and another time for some other inputted value.

    -----------------------------
    State  AX  Next instruction
    0      ?   INPUT
    1      1   CMP AX,1
    2      1   COND passes
    3      1   POINT AX,"one"
    4      ?   OUTPUT TEXT
    5      ?   -
    -----------------------------

    -----------------------------
    State  AX  Next instruction
    0      ?   INPUT
    1      ?   CMP AX,1
    2      ?   COND passes
    3      ?   POINT AX,"not one"
    4      ?   OUTPUT TEXT
    5      ?   JMP done
    6      ?   -
    -----------------------------

As we see from observing these state tables, due to the usage of CMP/COND, the order in which the instructions are executed will vary.

One problem with this piece of code is that it's somewhat confusing that the two code branches occur in the opposite order that they were in in the requirement. In other words, the requirement first mentioned printing "one" if the comparision succeeded, and printing "not one" if the comparision failed, but our code has the branches in the opposite order. This is because of the nature of JMP and COND. When a condition passes, the point of execution jumps to a later section of code, whereas a failed condition continues to execute right where it is. This means the "fails" branch occurs first, and the "passes" branch occurs second. Soon we'll see a way to rectify this situation.

Sometimes we want to test for a condition more complicated than just looking for one single value. For example, what if we want to branch depending on whether a value is greater than 15, or perhaps less than 60. If these cases were we want to check an entire range at once we can specify that we want a relative condition.

    Given a value in AX, print 'pass' if the value is greater than 60, or 'fail' if the value is less

    CMP    AX,60
    COND   > passes
    POINT  AX,"fail"
    OUTPUT TEXT
    JMP    done
    ; passes
    POINT  AX,"pass"
    OUTPUT TEXT
    ; done

Testing for greater than is just one of the specifications that can be included with COND. Also available, are

    COND   < label
    COND   = label
    COND   ! label

These stand for less than, equals, and does not equal. = is the default that is used in the case that no specification is given, similar to how INPUT and OUTPUT default to INPUT INTEGER and OUTPUT INTEGER if TEXT is not specified.

Now that we know how to test whether two values are unequal, let us return to the if/then/else problem.

    Have the user input a number. If that value is one, print 'one', otherwise print 'not one'

But this time, let's use COND ! instead of the default COND =.

    INPUT
    CMD    AX,1
    COND   ! else
    POINT  AX,"one"
    OUTPUT TEXT
    JMP    done
    ; else
    POINT  AX,"not one"
    OUTPUT TEXT
    ; done

Now the code matches the requirement much more closely. This is much easier to remember properly. As such, we can create the following template that can be employed whenever we need the if/then/else construct.

    CMP    <the 'if' comparision>
    COND   ! else
    <'then' code>
    JMP    done
    ; else
    <'else' code>
    ; done

Homework

"The CMP instruction can be used for more than just comparing integers. It can also tell you if two text pieces are the same (though not necessarily that they're different). Write some code that has the user input a piece of text, and then display 'same' if the text is equal to 'comparision'."

"Consider the following section of code."

    CMP    AX,30
    COND   > bigNumber
    ADD    AX,20
    CMP    AX,40
    COND   < inRange   
    MOV    AX,100
    ;bigNumber
    HALF   AX
    ;inRange
    MOV    AX,0

"Using this code, fill in the missing blanks in the following state tables"

    -----------------------------
    State  AX  Next instruction
    0      17  CMP AX,30
    1      17  COND > bigNumber
    2      17  ________________
    3     ___  ________________
    4     ___  ________________
    5     ___  MOV AX,0
    6       0  -
    -----------------------------

; in the above table, we can change AX into any value less than or equal to 19

    -----------------------------
    State  AX  Next instruction
    0      28  CMP AX,30
    1      28  COND > bigNumber
    2      28  ________________
    3     ___  ________________
    4     ___  ________________
    5     ___  ________________
    6     ___  ________________
    7      74  MOV AX,0
    8       0  -
    -----------------------------

; in the above table, we can change AX into any even value between 22 and 28

"Use the if/then/else template to write code for the following requirements"
next up previous
Next:Lesson 9 Up: Overview Previous: Lesson 2

by dlong@progmatism.com. Plz don't copy kthx.