Page 128 - Introduction to Microcontrollers Architecture, Programming, and Interfacing of The Motorola 68HC12
P. 128
4,5 A Simplified Two-Pass Assembler 105
PASS2 : CLR LCNTR ; clear location counter, which is object code index
LDX #SOURCE ; begin source scan: x-> first letter in source string
P21: LDAB 2, +x ; move past label and space, to get opcode character
LEAX 2 , X ; skip mnenmonic and space after it
CMPB #' D' ; if mnemonic is a directive D,
BEQ P22 ; go to get the hex value
JSR GETOPCD ; otherwise get the opcode, returns opcode in A
LDAB 1, x+ ; get symbolic name which is instruction effective address
JSR FINDLBL ; search labels, OR label value into opcode in A
BRA P23
P22: BSR GETHEX ; get hexadecimal value into A
P23 : LDAB LCNTR ; get location counter which is 8-bits, into B
EXG b, y ; expand B by filling with zero bits, to get 16-bit Y
STAA OBJECT, y ; store the opcode-address or the hex value
INC LCNTR ; increment location counter
LDAB #$d ; skip to end of the current source code line
P24: CMPB l,x+
BNE P24
TST 0, x ; get first character of next line; if null, exit
BNE P21 ; otherwise loop again
RTS
Figure 4.18. Assembler Pass 2
PAS SI (Figure 4.17) simply reads the characters from the source listing and inserts
labels and their values into the symbol table. As is typical of many programs, an initial
program segment initializes the variables needed in the rest of the subroutine, which is a
loop. This loop processes one line of assembly-language source code. If the line begins
with a label, it inserts the label and the current location counter into the symbol table. If
the line begins with a space, it skips the character. It then scans the characters until it
runs into the end of the line, indicated by a carriage return. Then it repeats the loop.
When a NULL character is encountered where a line should begin, it exits.
PASS2 (Figure 4.18) simply reads the characters from the source listing and
generates machine code, which is put into the object code vector. As in PASS1, an
initial program segment initializes the variables needed in the rest of the subroutine,
which is a loop. This loop processes one line of assembly-language source code. The
program skips the label and space characters. If the mnemonic is a D for define constant,
it calls a subroutine GETHEX to get the hexadecimal value; otherwise, it passes the
opcode mnemonic to a subroutine GETOPCD that searches the list of mnemonic codes,
returning the opcode. In the latter case, the subroutine FINDLBL finds the symbolic
label, ORing its value into the opcode. The machine code byte is then put into the object
code OBJECT.
GETOPCD (Figure 4.19) searches until it finds a match for the mnemonic. As it
searches for a match in B, it generates the machine code in A. Because there are no errors
in our source code, this extremely simple search procedure will always succeed in
returning the value for the matching mnemonic. Because the directive D has been
previously tested, if the opcode mnemonic is not an "L" or an "A" it must be "S."