A program loop is any set of instructions that are repeated within a program. A loop always ends with a branch or a jump instruction. This final instruction causes the flow to return to some location earlier in the code to repeat a set of instructions. Some program loops are conditional; therefore they loop back to an earlier part of the program only when some condition is true. Conditional loops are called finite loops
because they end whenever the condition is no longer true.
While and Until Loops
Often a program needs to execute a set of instructions only while a condition is true. This is called a WHILE loop. In other cases, the program may need to execute a set of instructions until some condition is true. This is called an UNTIL loop. A WHILE loop performs the branch test at the beginning of the loop; thus, the loop will never be executed if the condition is never true. An UNTIL loop performs the branch test at the end of the loop; thus, the loop is executed at least once. Figure 4.13 shows the flowcharts for the basic structure of the WHILE loop and the UNTIL loop. Either loop structure can be used to accomplish the same task. The only difference between the structures is the point at which the test is performed.
N CCR C flag Z flag C Z OR Test 0 0 0 1 0 1 0 1 1 1 1 1
C + Z = 0 only when C = 0 and Z = 0, as shown in the truth table.
pass fail Test 0? I Z V C H X S
Figure 4.12 BHI Branch Test
1. What class of branch instructions is required to implement the IF-THEN-ELSE structure?
2. What flowcharting symbol is required to show the IF-THEN-ELSE structure? 3. Which path will the program take (THEN path or ELSE path) if the branch test
fails?
111
For example, while the window is open the wind blows in, yet the wind will blow in until the window is closed. The process is the wind blowing in. Notice that the window must be opened before the wind can blow in. This is a WHILE condition. The wind will never blow in unless the window is first opened. The opposite situation is the UNTIL condition. If the window is already open, the wind will continue to blow until it is closed.
The UNTIL structure is easier to code. It requires only a single branch instruction. The WHILE structure requires an additional unconditional branch to skip past the process when the condition is no longer true. This difference can be illustrated with a simple time delay function.
First consider a time delay that utilizes the UNTIL structure, as shown in Figure 4.14. The process starts by initializing a counter. The X register will be used as the counter because it can hold a large count (up to 65,535), and the HC11 provides a decrement X instruction for the process of the loop. After the count has been initialized, the count is decremented once before the condition is checked. The desired time has expired when the count is equal to zero. If the count is not zero, the program loops back up to the decrement instruction to perform the process again. When the counter equals zero, the BNE instruction fails the branch test and the process drops out of the loop.
Process WHILE True DO False Continue on to other processes Condition? a) WHILE loop Process UNTIL True DO False Continue on to other processes Condition? b) UNTIL loop
Figure 4.13 WHILE and UNTIL Loop Flowcharts
BACK DO UNTIL BACK LDX #delay DEX BNE BACK Initialize Counter Decrement Counter Count = 0? Yes No
Figure 4.14 Time Delay Using UNTIL Structure
112
The value loaded into the X register during the initialization of the count determines how long this function waits.
The time delay can be accomplished with the WHILE structure, as shown in Figure 4.15. The process starts by initializing a counter. After the count has been initialized, the condition is checked. If the count is zero, the program branches out of the while loop and the process is complete; otherwise, it drops into the decrement process. After the count is decremented, the unconditional branch causes the program to loop back to perform the test again. This repeats until the count is decremented to zero.
Timing Loops
Since each instruction requires a fixed number of machine cycles to perform the fetch and execution of the instruction, programs can be written to cause things to happen at specific points in time. There are two instructions that can be used to help cause specific timing conditions: NOP and BRN. These instructions are summarized in Figure 4.16. The NOP instruction stands for “No operation.” It takes two machine cycles to do nothing. It is primarily for timing control within a program. It can also be a valuable tool during software debugging. An instruction within a program can be temporarily disabled by replacing it with an NOP. The BRN instruction stands for “Branch Never.” It takes three machine cycles to perform a branch test that always fails and then falls through to the next instruction, in essence doing nothing. It is primarily used during the troubleshooting of a program to temporarily disable another branch instruction.
Initialize Counter Count ≠ 0? Decrement Counter No WHILE DO BACK Yes BACK LDX #$delay BRA OUT DEX BRA BACK OUT …
Figure 4.15 Time Delay Using WHILE Structure
Mnemonic Description Function IMM DIR EXT INDX INDY INH REL S X H I N Z V C
NOP No operation Fetch opcode
and do nothing - - - X - - - -
BRN Branch never Perform branch test and fall through
- - - X - - - -
Figure 4.16 Time Delay Instructions 113
Because it requires three machine cycles, it can be used in conjunction with the NOP to create and odd or even number of machine cycles within a timing loop.
The NOP and BRN instructions can be used anywhere in a program to just wait two or three machine cycles. They have no other effect on the processes. If each machine cycle is 500 ns, the NOP would create a time delay of 1 µs and the BRN would create a time delay of 1.5 µs. This may not seem like a very long time, but to a computer, it is long enough to wait on a slow memory or I/O device before proceeding with the next operation. Inside a timing loop, like the loop presented in Figure 4.14, one of these time delay instructions can greatly increase the length of the loop. Outside the loop, they could require an extra two or three machine cycles to make the time delay more precise.
Self-Test Questions 4.6
Summary
This chapter focused on the instructions that have the job of controlling or altering the flow of a program. The JMP and BRA instructions are used to unconditionally change the flow of the program. There also is a large group of conditional branch instructions that perform a branch test before the branch takes place. If the test fails, the program will not branch. It falls through to the instruction following the branch instruction. The jump instruction uses an absolute 16-bit address to designate the destination address of the jump. Any address can be designated as the destination address of the jump instruction. Branch instructions use a relative address to designate the destination address. The final destination must be calculated from the PC and the relative address. Since the relative address is only an 8-bit address, the destination address is limited to a small range around the current PC (128 bytes backwards, 127 bytes forward).
Because of the ability of conditional branch instructions to perform branch tests, they can be used in various conditional-programming structures. The IF-THEN-ELSE structure allows a process to occur only IF a condition is true. The WHILE structure allows a process only while some condition is true, and the UNTIL structure allows the process to continue until some condition is true.
Chapter Questions
Section 4.1
1. What is the destination address of a jump instruction?
2. How are destination addresses usually designated in the code so that the programmer does not have to calculate the exact address?
1. What is a finite loop?
2. What is the difference between a WHILE loop and an UNTIL loop? 3. Why does the UNTIL structure use fewer lines of code to implement? 4. What is one function of the NOP instruction?
114
Section 4.2
3. What effect does a branch instruction have on the program counter? 4. Are relative addresses signed or unsigned values?
5. What is the largest number of addresses that a program can branch forward? 6. What is the largest number of addresses that a program can branch backward? 7. Which address is used as the reference before the branch is calculated? 8. If a BRA instruction is located at $0134, what is the maximum forward
destination address?
9. If a BRA instruction is located at $01CD, what is the maximum backward destination address?
Section 4.3
10. Which CCR flags are used by the conditional branch instructions for the branch tests?
11. What is the conditional branch test for the BLT instruction?
12. How is it determined if the branch test in question 11 passes or fails? 13. Repeat question 12 for the BHI instruction.
Section 4.4
14. What do compare instructions actually do?
15. What is the difference between a subtraction and a compare instruction? 16. On the HC11, is there any other way to compare two numbers, besides
subtracting them?
Section 4.5
17. Why is a conditional branch instruction required for an IF-THEN-ELSE structure?
18. Could an IF-THEN-ELSE structure be written that tests to see if something is “not true”?
Section 4.6
19. What is the functional difference between a WHILE and an UNTIL loop? 20. Explain the idea behind a finite loop.
21. Which finite loop is easier to code, WHILE or UNTIL? Why?
22. What combination of instructions could be used to cause a delay of five machine cycles?