7.3.5 Creating Local Variables Automatically

Section 7.3.4 described how to create local variables on the stack. This section shows you how to automate the process with the LOCAL directive.

Summary: The LOCAL directive generates code to set up the stack for local variables.

You can use the LOCAL directive to save time and effort when working with local variables. When you use this directive, simply list the variables you want to create, giving a type for each one. The assembler calculates how much space is required on the stack. It also generates instructions to properly decrement SP (as described in the previous section) and to reset SP when you return from the procedure.

When you create local variables this way, your source code can then refer to each local variable by name rather than as an offset of the stack pointer. Moreover, the assembler generates debugging information for each local variable.

The procedure in the previous section can be generated more simply with the following code:

task PROC NEAR arg:WORD

LOCAL loc:WORD

.

.

.

mov loc, 3 ; Initialize local variable

add ax, loc ; Add local variable to AX

sub arg, ax ; Subtract local from argument

. ; Use "loc" and "arg" in other operations

.

.

ret

task ENDP

The LOCAL directive must be on the line immediately following the PROC statement. It cannot be used after the first instruction in a procedure. The LOCAL directive has the following syntax:

LOCALvardef[[,vardef]]...

Each vardef defines a local variable. A local variable definition has this form:

label[[ [count] ]][[:qualifiedtype]]

These are the parameters in local variable definitions:

Argument Description
label The name given to the local variable. You can use this name to access the variable.
count The number of elements of this name and type to allocate on the stack. You can allocate a simple array on the stack with count. The brackets around count are required. If this field is omitted, one data object is assumed.
qualifiedtype A simple MASM type or a type defined with other types and attributes. See Section 1.2.6, “Data Types,” for more information.

If the number of local variables exceeds one line, you can place a comma at the end of the first line and continue the list on the next line. Another method is to use several consecutive LOCAL directives.

Summary: You must initialize local variables.

The assembler does not initialize local variables. Your program must include code to perform any necessary initializations. For example, the following code fragment sets up a local array and initializes it to zero:

arraysz EQU 20

aproc PROC USES di

LOCAL var1[arraysz]:WORD, var2:WORD

.

.

.

; Initialize local array to zero

push ss

pop es ; Set ES=SS

lea di, var1 ; ES:DI now points to array

mov cx, arraysz ; Load count

sub ax, ax

rep stosw ; Store zeros

; Use the array...

.

.

.

ret

aproc ENDP

Even though you can reference stack variables by name, the assembler treats them as offsets from BP, and they are not visible outside the procedure. In this procedure, array is a local variable.

index EQU 10

test PROC NEAR

LOCAL array[index]:WORD

.

.

.

mov bx, index

; mov array[bx], 5 ; Not legal!

The second MOV statement may appear to be legal, but since array is an offset of BP, this statement is the same as

; mov [bp + bx + arrayoffset], 5 ; Not legal!

BP and BX can be added only to SI and DI. This example would be legal, however, if the index value were moved to SI or DI. This type of error in your program can be difficult to find unless you keep in mind that local variables in procedures are offsets of BP.