ENABLE INTERRUPTS
MEMORY RESERVATION
DS Directive
The DS directive can be used to define a block of storage.
Label Opcode Operand
optional: DS expression
Each symbol in the expression must be previously defined. The value of 'expression' specifies the number of bytes to be reserved for data storage. In theory, this value may range from OOH through OFFFFH; in practice, you will reserve no more storage than will fit in your available memory and still leave room for the program.
Any symbol appearing in the operand expression must be defined before the assembler reaches the DS directive.
Unlike the DB and DW directives, DS assembles no data into your program. The contents of the reserved storage are unpredictable when program execution is initiated.
If the optional label is present, it is assigned the current value of the location counter, and thus references the first byte of the reserved memory block.
If the value of the operand expression is zero, no memory is reserved. However, if the optional label is present, it is assigned the current value of the location counter.
The DS directive reserves memory by incrementing the location counter by the value of the operand expression.
Example:
TIVBUF: DS 72 ;RESERVE 72 BVTES FOR
;A TERMINAL OUTPUT BUFFER
Programming Tips: Data Description and Access Random Access Versus Read Only Memory
When coding data descriptions, keep in mind the mix of ROM and RAM in your application.
Generally, the DB and DW directives define constants, items that can be assigned to ROM. Vou can use these items in your program, but you cannot modify them. If these items are assigned to RAM, they have an initial value that your program can modify during execution. Notice, however, that these initial values must be reloaded into memory prior to each execution of the program.
Variable data in memory must be assigned to RAM.
Data Description
Before coding your program, you must have a thorough understanding of its input and output data. But you'll probably find it more convenient to postpone coding the data descriptions until the remainder of the program is fairly well developed. This way you will have a better idea of the constants and workareas needed in your program.
Also, the organization of a typical program places instructions in lower memory, followed by the data, followed by the stack.
Data Access
Accessing data from memory is typically a two-step process: First you tell the processor where to find the data, then the processor fetches the data from memory and loads it into a register, usually the accumulator. Therefore, the following code sequences have the identical effect of loading the ASCII character A into the accumulator.
AAA: DB 'A' ALPHA: DB 'ABC'
LXI B,AAA LXI B,ALPHA
LDAX B LDAX B
Chapter 4. Assembler Directives
In the examples, the LXI instructions load the address of the desired data into the Band C registers. The LDAX instructions then load the accumulator with one byte of data from the address specified in the Band C registers.
The assembler neither knows nor cares that only one character from the three-character field ALPHA has been accessed. The program must account for the characters at ALPHA+ 1 and ALPHA+2, as in the following coding sequence:
ALPHA: DB 'ABC' ;DEFINE ALPHA
LXI B,ALPHA ;LOAD ADDRESS OF ALPHA
LDAX B ;FETCH 1 ST ALPHA CHAR
INX B ;SET B TO ALPHA+l
LDAX B ;FETCH 2ND ALPHA CHAR
INX B ;SET B TO ALPHA+2
LDAX B ;FETCH 3RD ALPHA CHAR
The coding above is acceptable for short data fields like ALPHA. For longer fields, you can conserve memory by setting up an instruction sequence that is executed repeatedly until the source data is exhausted.
Add Symbols for Data Access
The following example was presented earlier as an illustration of the DS directive:
Label Opcode Operand Comment
TTYBUF: DS 72 ;RESERVE TTY BUFFER
To access data in this buffer using only expressions such as TTYBUF+l, TTYBUF+2, ... TTYBUF+72 can be a laborious and confusing chore, especially when you want only selected fields from the buffer. You can simplifY this task by subdivid.ing the buffer with the EQU directive:
Label Opcode Operand Comment
TTYBUF: DS 72 ;RESERVE TTY BUFFER
ID EQU TTYBUF ;RECORD IDENTIFIER
NAME EQU TTYBUF+6 ;20-CHAR NAME FIELD
NUMBER EQU TTYBUF+26 ;10-CHAR EMPLOYEE NUMBER
DEPT EQU TTYBUF+36 ;5-CHAR DEPARTMENT NUMBER
SSNO EQU TTYBUF+41 ;SOCIAL SEC. NUMBER
DOH EQU TTYBUF+50 ;DATE OF HIRE
Subdividing data as shown in the example simplifies data access and provides useful documentation throughout your program. Notice that these EQU directives can be inserted anywhere within the program as you need them, but coding them as shown in the example provides a more useful record description.
CONDITIONAL ASSEMBLY
The IF, ELSE, and ENOIF directives enable you to assemble portions of your program conditionally, that is, only if certain conditions that you specify are satisfied.
Each symbol within an IF-ENOl F block must be previously defined. Conditional assembly is especially useful when your application requires custom programs for a number of common options. As an example, assume that a basic control program requires customizing to accept input from one of six different sensing devices and to drive one of five different control devices. Rather than code some thirty separate programs to account for all the possibilities, you can code a single program. The code for the individual sensors and drivers must be enclosed by the conditional directives. When you need to generate a custom program, you can insert SET directives near the beginning of the source program to select the desired sensor and driver routines.
IF, ELSE, ENDIF Directives
Because these directives are used in conjunction, they are described together here.
Label Opcode Operand
optional: IF expression
optional: ELSE
optional: ENOIF
Each symbol in the expression must be previously defined. The assembler evaluates the expression in the operand field of the I F directive. If bit 0 of the resulting value is one (TRUE), all instructions between the I F directive and the next ELSE or ENOl F directive are assembled. When bit 0 is zero (FALSE) these instructions are ignored.
(A TRUE expression evaluates to OFFFFH and FALSE to OH; only bit zero need be tested.)
All statements included between an I F directive and its required associated ENOl F directive are defined as an IF-ENOIF block. The ELSE directive is optional, and only one ELSE directive may appear in an IF-ENOIF block. When included, ELSE is the converse of IF. When bit 0 of the expression in the I F directive is zero, all statements between ELSE and the next ENOl F are assembled. If bit 0 is one, these statements are ignored.
Operands are not allowed with the ELSE and ENOIF directives.
An IF-ENOl F block may appear within another IF-ENOl F block. These blocks can be nested to eight levels.
Macro definitions (explained in the next chapter) may appear within an IF-ENOl F block. Conversely, IF-EN 01 F blocks may appear within macro definitions. In either case, you must be certain to terminate the macro definition
Chapter 4. Assembler Directives
or I F-ENDI F block so that it can be assembled completely. For example, when a macro definition begins in an IF block but terminates after an ELSE directive, only a portion of the macro can be assembled. Similarly, an IF-ENDIF block begun within a macro definition must terminate within that same macro definition.
Example 1.
NOTE
Caution is required when symbols are defined in IF -ENDI F blocks and referenced elsewhere within the program. These symbols are undefined when the evaluation of the I F ex-pression suppresses the assembly of the IF-ENDIF block.
Simple I F-ENDI F Block (where TYPE has been previously defined):
COND1: IF TYPE EO 0
ENDIF
Example 2. IF-ELSE-ENDIF Block:
COND2: IF TYPE EO 0
ELSE
ENDIF
;ASSEMBLED IF TYPE = 0'
;15 TRUE
;ASSEMBLED IF TYPE
=
0';15 TRUE
;ASSEMBLED IF TYPE = 0'
;15 FALSE
Example 3. Nested IF's:
COND3: IF TYPE EO 0
LEVEL
IF MODE EO 1
ENDIF ELSE
;ASSEMBLED IF TYPE = 0'
;15 TRUE
;ASSEMBLED IF 'TYPE = 0'
;AND 'MODE
=
l' ARE BOTH;TRUE
LEVEL 2
;ASSEMBLED IF TYPE = 0'
;15 FALSE IF MODE EO 2
LEVEL ELSE
ENDIF ENDIF
;ASSEMBLED IF 'TYPE = 0'
;15 FALSE AND 'MODE = 2'
;15 TRUE
;ASSEMBLED IF 'TYPE = 0'
;AND 'MODE = 2' ARE BOTH
;FALSE