7.2.2 Writing Loop Conditions

You can express the conditions of the .IF, .REPEAT, and .WHILE directives using relational operators, and you can express the attributes of the operand with the PTR operator. To write loop conditions, you also need to know how the assembler evaluates the operators and operands in the condition. This section explains the operators, attributes, precedence level, and expression evaluation order for the conditions used with loop-generating directives.

7.2.2.1 Expression Operators

The binary relational operators in MASM 6.0 high-level control structures are listed below. The same binary operators are used in C. These operators generate MASM compare, test, and conditional jump instructions.

Operator Meaning
== Equal
!= Not equal
> Greater than
>= Greater than or equal to
< Less than
<= Less than or equal to
& Bit test
! Logical NOT
&& Logical AND
|| Logical OR

A condition without operators (other than !) tests for nonzero as it does in C. For example, .WHILE (x) is the same as .WHILE (x != 0), and .WHILE (!x) is the same as .WHILE (x == 0).

Summary: Flag names can be operands in a condition.

You can also use the flag names (ZERO?, CARRY?, OVERFLOW?, SIGN?, and PARITY?) as operands in conditions with the high-level control structures as in .WHILE (CARRY?). The particular flag set determines the outcome of the condition. Use flag names when you want to generate the compare or other instructions that set the flags.

7.2.2.2 Signed and Unsigned Operands

Summary: Registers, constants, and memory locations are unsigned by default.

Expression operators generate unsigned jumps by default. However, if either side of the operation is signed, then the entire operation is considered signed. The default for the operands in registers, constants, and named memory locations is also to be unsigned.

You can use the PTR operator to tell the assembler that a particular operand in a register or constant is a signed number, as in these examples:

.WHILE SWORD PTR [bx] <= 0

.IF SWORD PTR mem1 > 0

Without the PTR operator, the assembler would treat the contents of BX as an unsigned value.

You can also specify the size attributes of operands in memory locations with SBYTE, SWORD, and SDWORD, for use with .IF, .WHILE, and .REPEAT.

.DATA

mem1 SBYTE ?

mem2 WORD ?

.IF mem1 > 0

.WHILE mem2 < bx

.WHILE SWORD PTR ax < count

7.2.2.3 Precedence Level

As with C, you can concatenate conditions with the && operator for AND, the || operator for OR, and the ! operator for negate. The precedence level is !, &&, and ||, with ! having the highest precedence. Like expressions in high-level languages, associativity is evaluated left to right.

7.2.2.4 Expression Evaluation

The assembler evaluates conditions created with high-level control structures according to short-circuit evaluation. If the evaluation of a particular condition automatically determines the final result (such as a condition that evaluates to false in a compound statement concatenated with AND), the evaluation does not continue.

For example, in this .WHILE statement,

.WHILE (ax > 0) && (WORD PTR [bx] == 0)

the assembler evaluates the first condition. If this condition is false (that is, if AX is less than or equal to 0), the evaluation is finished. The second condition is not checked and the loop does not execute, because a compound condition containing a && requires both expressions to be true for the entire condition to be true.