Hardware Reference
In-Depth Information
memory for the immediate operand at the end of the program and generates an in-
struction that references it. For instance, the IBM 360 mainframe and its suc-
cessors have no immediate instructions. Nevertheless, programmers may write
L 14,=F 5
to load register 14 with a full word constant 5. In this manner, the programmer
avoids explicitly writing a pseudoinstruction to allocate a word initialized to 5, giv-
ing it a label, and then using that label in the L instruction. Constants for which the
assembler automatically reserves memory are called literals . In addition to saving
the programmer a little writing, literals improve the readability of a program by
making the value of the constant apparent in the source statement. Pass one of the
assembler must build a table of all literals used in the program. All three of our ex-
ample computers have immediate instructions, so their assemblers do not provide
literals. Immediate instructions are quite common nowadays, but formerly they
were unusual. It is likely that the widespread use of literals made it clear to ma-
chine designers that immediate addressing was a good idea. If literals are needed,
a literal table is maintained during assembly, with a new entry made each time a
literal is encountered. After the first pass, this table is sorted and duplicates re-
moved.
Figure 7-9 shows a procedure that could serve as a basis for pass one of an
assembler. The style of programming is noteworthy in itself. The procedure
names have been chosen to give a good indication of what the procedures do.
Most important, Fig. 7-9 represents an outline of pass one which, although not
complete, forms a good starting point. It is short enough to be easily understood
and it makes clear what the next step must be—namely, to write the procedures
used in it.
Some of these procedures will be relatively short, such as check for symbol ,
which just returns the symbol as a character string if there is one and null if there is
not. Other procedures, such as get length of type1 and get length of type2 , may
be longer and may call other procedures. In general, the number of types will not
be two, of course, but will depend on the language being assembled and how many
types of instructions it has.
Structuring programs in this way has other advantages in addition to ease of
programming. If the assembler is being written by a group of people, the various
procedures can be parceled out among the programmers. All the (nasty) details of
getting the input are hidden away in read next line . If they should change—for
example, due to an operating system change—only one subsidiary procedure is
affected, and no changes are needed to the pass one procedure itself.
As it reads the program, pass one of the assembler has to parse each line to
find the opcode (e.g., ADD ), look up its type (basically, the pattern of operands),
and compute the instruction's length. This information is also needed on the sec-
ond pass, so it is possible to write it out explicitly to eliminate the need to parse the
line from scratch next time. However, rewriting the input file causes more I/O to
 
Search WWH ::




Custom Search