11.3.3 Implementing selection constructs in assembly language
Now that we have a basic understanding of variables, assignment, and sequence in assembly language programs, we turn our attention to the issue of implementing the high-level selection, or “if”, construct. Figure 11.5 contains an assembly language program that determines whether an individual is a minor or not based on his or her age. In this example, the value “1” is used to mean “true” and the value “0” false.
The high-level code segment begins by assigning a “0” to “minor”, indicating that the individual is initially assumed to be an adult. The value held in the “age” variable is then compared to 18 and if “age” is less than 18, “minor” is set to “1” indicating the individual is now known to be a minor. Otherwise, “minor” is left unchanged; it retains its initial value of 0 meaning the individual is not a minor.
The assembly language program that implements this high-level code segment introduces two new instructions: COMPARE and BRANCH. These two statements can be used together to implement the semantics of high-level “if” constructs. The program also illustrates that any statement in an assembly language program may have a label associated with it, not just .BLOCK and .WORD statements.
High-level Watson JavaScript code:
Equivalent Assembly Language code:
Figure 11.5: High-level and assembly code to determine whether a person is a minor.
Let’s now walk through the actions of this assembly language program. First, the variables AGE and MINOR are declared. Since AGE must be initialized to some valid value, I arbitrarily decided to set it to 2 via the .WORD command. (In other words, I am assuming the person currently being “processed” is two years old.) MINOR is declared via .BLOCK since its value will be set within the code.
Once the variables have been declared and age initialized, the high-level statement that sets MINOR to zero can be implemented. This task can be accomplished by loading a zero into a register (via LOADIMM) and then storing (via STORE) that register’s value into the main memory location labeled MINOR.
At this point you might be wondering why I didn’t simply declare MINOR to be zero via:
MINOR .WORD 0
While it is certainly true that the .WORD statement initializes the value of MINOR to zero, the statement does not quite reflect the exact meaning of the high-level language code. The high-level code does not declare MINOR and initialize it as part of the declaration process (as the .WORD statement does). Instead, the high-level code places a value of zero into the variable “minor” via an explicit assignment statement.
In general, .WORD statements should not be used to implement the actions of assignment statements. The .WORD statement is a way of declaring a variable in assembly language and giving it an initial value at the same time. Often, I use these initial values in the example programs to represent input values – such as an age of two in the current example.
Now that MINOR has been given its default value of 0, or “false”, we can turn our attention to the “if-then” construct. The “if-then” construct consists of two distinct parts: the “if” condition test and the “then” actions (to be executed only if the condition is true). This high-level construct can be built from COMPARE, BRANCH and JUMP statements – together with two strategically placed instruction labels. Under this scheme, the COMPARE and BRANCH instructions will be used to implement the condition test and to transfer control directly to the “then” actions if the condition is true. The JUMP will be used to skip over the “then” actions if the condition is false.
The general form of the COMPARE statement is:
COMPARE first operand register, second operand register
The statement examines the values held in the two registers to determine the relationship that exists between them. Valid relationships include:
A BRANCH instruction usually appears immediately following a COMPARE. The BRANCH instruction is a low-level command that allows the Watson Virtual Machine to execute different parts of a program depending on the results of a test condition. The general form of the BRANCH instruction is:
BRANCH test condition, target label
where test condition is usually one of the six conditions resulting from a COMPARE:
EQ, NE, LT, LE, GT, GE
and target label is a label associated with a “target” instruction.
BRANCH works in the following way. If the test condition is true then program control will branch to the target instruction and execution will continue from that point on. If the test condition is false, the current sequence of instructions will not be interrupted – execution will continue with the statement immediate following the BRANCH.
The general form of the JUMP instruction is:
JUMP target label
Both the JUMP and BRANCH statements are similar in that they are both used to break out of the normal sequential flow of control from one statement to the next. The difference is that BRANCH is a “conditional” statement. It only transfers control to its target statement if its test condition is true. JUMP, on the other hand, is an “unconditional” statement. It always transfers control its target statement.
It is interesting to note that since JUMP unconditionally transfers control to its target statement, in order for the statement that physically follows the JUMP to ever be executed, it must contain a label that is the target of some other JUMP or BRANCH instruction. Otherwise, the program will have no way of referencing that instruction.
In the example of Figure 11.5, the variable AGE is to be compared to the value 18. In order to do so, the values must first be loaded into registers. This is accomplished by loading AGE into register A and issuing a load immediate of 18 into register B. The actual statements to accomplish this task are:
Notice that the LOAD statement has been labeled IF, since it marks the beginning of the assembly language code for implementing the high-level “if” statement. While this label isn’t strictly necessary in order to implement an “if” construct, it does make the assembly code somewhat easier to read.
Once these values have been copied into the registers, they can be compared via:
COMPARE REGA, REGB
If the value held in register A (age) is less than the value held in register B (18), the “then” instructions should be executed which will set MINOR to 1, as the person is a minor. The following assembly language instruction causes control to be transferred to the statement labeled THEN.
BRANCH LT, THEN
If the condition test is not true, the BRANCH statement will have no effect and control will be transferred to the statement immediately following it. Thus, in the event that age is not less than 18 (i.e., it is greater than or equal to 18) the statement
JUMP ENDIF
will be executed. This statement will have the effect of “jumping” over the statements comprising the “then” block.
Assuming the condition test was true, the “then” actions of the “if” construct are executed. These actions place the value 1 into the variable MINOR.
The “then” code loads a 1 into register 1 via a load immediate statement, and then copies that value into the memory location associated with the variable MINOR via the STORE statement. The result is that a 1 is placed into MINOR. Note that the load immediate statement sports a THEN label. This label is necessary for the program to execute properly since it is the target of the BRANCH instruction.
The final statement of this program serves as the target of the JUMP instruction and is labeled ENDIF.
ENDIF HALT
This statement will always execute when the program is run, regardless of whether the condition was true or false.
Figure 11.6: High-level and assembly code to increment minor and adult counters.
Figure 11.6 presents a program that extends the ideas of Figure 11.5 from the “if-then” construct to the more general “if-then-else” construct.
The purpose of the program of Figure 11.6 is to illustrate how a high-level “if-then-else” structure can be implemented as a series of assembly language instructions. The actual high-level “if” construct adds one to either the number of “adults” or the number of “minors” – depending on whether the value of “age” is less than 18 or not. This high-level construct is not really a complete program, in the sense that it would need to be placed in a repetition structure (loop) in order to “process” more than one person.
(a) Template for constructing assembly language version of “if-then”
(b) Template for constructing assembly language version of “if-then-else”
Figure 11.7: General templates for implementing selection constructs in assembly
Figure 11.7 summarizes the process of translating high-level “if-then” and “if-then-else” constructs to assembly language. Part (a) of the figure contains a template for generating an assembly version of an “if-then” construct. Part (b) presents a template for generating an assembly version of an “if-then-else” construct.
Exercises for Section 11.3.3