1.2.4 Integer Constants and Constant Expressions

An integer constant is a series of one or more numerals followed by an optional radix specifier. For example, in these statements

mov ax, 25

mov ax, 0B3h

the numbers 25 and 0B3h are integer constants. The h appended to 0B3 is a radix specifier. The specifiers are

y for binary (or b if radix is less than or equal to 10)

o or q for octal

t for decimal (or d if radix is less than or equal to 10)

h for hexadecimal

Summary: The default radix is decimal.

Radix specifiers can be either uppercase or lowercase letters; sample code in this book uses lowercase. If no radix is specified, the assembler interprets the integer according to the current radix. The default radix is decimal, but it can be changed with the .RADIX directive.

Hexadecimal numbers must always start with a decimal digit (0–9). If necessary, add a leading zero to distinguish between symbols and hexadecimal numbers that start with a letter. For example, ABCh is interpreted as an identifier. The hexadecimal digits A through F can be either uppercase or lowercase letters. Sample code in this book uses uppercase letters.

Summary: Values of integer constants and expressions are known at assembly time.

Constant expressions contain integer constants and (optionally) operators such as shift, logical, and arithmetic operators, and can be evaluated. The assembler evaluates them at assembly time. (In addition to constants, expressions can contain labels, types, registers, and their attributes.) Constant expressions do not change value during program execution.

Symbolic Integer Constants

You can define symbolic integer constants with either of the data assignment directives, EQU or the equal sign (=). These directives assign values to symbols during assembly, not during program execution. Symbols defined as integer constants can then be used in subsequent statements as immediate operands having the assigned value. Symbolic constants are often used to assign mnemonic names to constant values, which makes your code more readable and easier to maintain.

The assembler does not allocate data storage when you use either EQU or =. Instead, it replaces each occurrence of the symbol with the value of the expression.

Summary: Symbols defined with EQU cannot be redefined.

The difference between EQU and = is that integers defined with the = directive can be changed in your source code, but those defined with EQU cannot. Once a symbolic integer constant has been defined with the EQU directive, attempting to redefine it generates an error. The syntax is

symbol EQU expression

The symbol must be a unique name. The expression can be an integer, a constant expression, a one- or two-character string constant (four-character on the 80386/486), or an expression that evaluates to an address. If a constant value used in numerous places in the source code needs to be changed, you modify the expression in one place rather than throughout the source code.

The following example shows the correct use of EQU to define symbolic integers.

column EQU 80 ; Constant - 80

row EQU 25 ; Constant - 25

screen EQU column * row ; Constant - 2000

line EQU row ; Constant - 25

.DATA

.CODE

.

.

.

mov cx, column

mov bx, line

The value of a symbol defined with the = directive can be different at different places in the source code. However, a constant value is assigned during assembly for each use, and that value does not change at run time.

The syntax for the = directive is

symbol = expression

Size of Constants

The default word size for MASM 6.0 expressions is 32 bits. This behavior can be modified using OPTION EXPR16 or OPTION M510. Both of these options set the expression word size to 16 bits, but OPTION M510 affects other assembler behavior as well (see Appendix A).

It is illegal to change the expression word size once it has been set with OPTION M510, OPTION EXPR16, or OPTION EXPR32, but you can repeat the same directive in a file. This can be useful for putting an OPTION EXPR16 in every include file, for example.