PROGRAM CONTROL INSTRUCTIONS:CONTROLLING THE FLOW OF THE PROGRAM.

CONTROLLING THE FLOW OF THE PROGRAM

It is much easier to use the assembly language statements .IF, .ELSE, .ELSEIF, and .ENDIF to control the flow of the program than it is to use the correct conditional jump statement. These statements always indicate a special assembly language command to MASM. Note that the control flow assembly language statements beginning with a period are only available to MASM version 6.xx, and not to earlier versions of the assembler such as 5.10. Other statements developed in this chapter include the .REPEAT–.UNTIL and .WHILE–.ENDW statements. These statements (the dot commands) do not function when using the Visual C++ inline assembler.

Example 6–8(a) shows how these statements are used to control the flow of a program by testing AL for the ASCII letters A through F. If the contents of AL are A through F, 7 is subtracted from AL.

Accomplishing the same task using the Visual C++ inline assembler is usually handled in C++ rather than in assembly language. Example 6–8(b) shows the same task using the inline assembler in Visual C++ and conditional jumps in assembly language. It also shows how to use a label in an assembly block in Visual C++. This illustrates that it is more difficult to accomplish the same task without the dot commands. Never use uppercase for assembly language commands with the inline assembler because some of them are reserved by C++ and will cause problems.

Program Control InstructionsA-0218

In Example 6–8(a) notice how the && symbol represents the AND function in the .IF statement. There is no .if in Example 6–8(b) because the same operation was performed by using a few compare (CMP) instructions to accomplish the same task. See Table 6–3 for a complete list of relational operators used with the .IF statement. Note that many of these conditions (such as &&) are also used by many high-level languages such as C/C++.

Example 6–9 shows another example of the conditional .IF directive that converts all ASCII-coded letters to uppercase. First, the keyboard is read without echo using DOS INT 21H function 06H, and then the .IF statement converts the character into uppercase, if needed. In this example, the logical AND function (&&) is used to determine if the character is in lowercase. If it is lowercase, 20H is subtracted, converting to uppercase. This program reads a key from the

Program Control InstructionsA-0219

keyboard and converts it to uppercase before displaying it. Notice also how the program terminates when the control C key (ASCII = 03H) is typed. The .LISTALL directive causes all assembler- generated statements to be listed, including the label @Startup generated by the .STARTUP directive. The .EXIT directive also is expanded by .LISTALL to show the use of the DOS INT 21H function 4CH, which returns control to DOS.

Program Control InstructionsA-0220

In this program, a lowercase letter is converted to uppercase by the use of the .IF AL >= ‘a’ && AL <= ‘z’ statement. If AL contains a value that is greater than or equal to a lowercase a, and less than or equal to a lowercase z (a value of a through z), the statement between the .IF and .ENDIF executes. This statement (SUB AL,20H) subtracts 20H from the lowercase letter to change it to an uppercase letter. Notice how the assembler program implements the .IF statement (see lines that begin with *). The label @C0001 is an assembler-generated label used by the conditional jump statements placed in the program by the .IF statement.

Another example that uses the conditional .IF statement appears in Example 6–10. This program reads a key from the keyboard, and then converts it to hexadecimal code. This program is not listed in expanded form.

In this example, the .IF AL >=‘a’ && AL<=‘f’ statement causes the next instruction (SUB AL,57H) to execute if AL contains letters a through f, converting them to hexadecimal. If it is not between letters a and f, the next .ELSEIF statement tests it for the letters A through F. If it is the letters A through F, 37H is subtracted from AL. If neither condition is true, 30H is subtracted from AL before AL is stored at data segment memory location TEMP. The same conversion can be performed in a C++ function as illustrated in the program snippet of Example 6–10(b).

Program Control InstructionsA-0221

WHILE Loops

As with most high-level languages, the assembler also provides the WHILE loop construct, available to MASM version 6.x. The .WHILE statement is used with a condition to begin the loop, and the .ENDW statement ends the loop.

Example 6–11 shows how the .WHILE statement is used to read data from the keyboard and store it into an array called BOP until the enter key (0DH) is typed. This program assumes that BUF is stored in the extra segment because the STOSB instruction is used to store the key- board data in memory. Note that the .WHILE loop portion of the program is shown in expanded form so that the statements inserted by the assembler (beginning with a *) can be studied. After the Enter key (0DH) is typed, the string is appended with a $ so it can be displayed with DOS INT 21H function number 9.

Program Control InstructionsA-0222Program Control InstructionsA-0223

The program in Example 6–11 functions perfectly, as long as we arrive at the .WHILE statement with AL containing some other value except 0DH. This can be corrected by adding a MOV AL,0DH instruction before the .WHILE statement in Example 6–11. Although not shown in an example, the .BREAK and .CONTINUE statements are available for use with the while loop. The .BREAK statement is often followed by the .IF statement to select the break condition as in .BREAK .IF AL == 0DH. The .CONTINUE statement, which can be used to allow the DO–.WHILE loop to continue if a certain condition is met, can be used with .BREAK. For example, .CONTINUE .IF AL == 15 allows the loop to continue if AL equals 15. Note that the .BREAK and .CONTINUE commands function in the same manner in a C++ program.

REPEAT-UNTIL Loops

Also available to the assembler is the REPEAT–UNTIL construct. A series of instructions is repeated until some condition occurs. The .REPEAT statement defines the start of the loop; the end is defined with the .UNTIL statement, which contains a condition. Note that .REPEAT and .UNTIL are available to version 6.x of MASM.

If Example 6–11 is again reworked by using the REPEAT-UNTIL construct, this appears to be the best solution. See Example 6–12 for the program that reads keys from the keyboard and stores keyboard data into extra segment array BUF until the enter key is pressed. This pro- gram also fills the buffer with keyboard data until the Enter key (0DH) is typed. Once the Enter key is typed, the program displays the character string using DOS INT 2lH function number 9, after appending the buffer data with the required dollar sign. Notice how the .UNTIL AL == 0DH statement generates code (statements beginning with *) to test for the Enter key.

Program Control InstructionsA-0224

There is also an .UNTILCXZ instruction available that uses the LOOP instruction to check CX for a repeat loop. The .UNTILCXZ instruction uses the CX register as a counter to repeat a loop a fixed number of times. Example 6–13 shows a sequence of instructions that uses the .UNTILCXZ instruction used to add the contents of byte-sized array ONE to byte- sized array TWO. The sums are stored in array THREE. Note that each array contains 100 bytes of data, so the loop is repeated 100 times. This example assumes that array THREE is in the extra segment, and that arrays ONE and TWO are in the data segment. Notice how the LOOP instruction is inserted for the .UNTILCXZ.

Program Control InstructionsA-0225

Leave a comment

Your email address will not be published. Required fields are marked *