Example PDP-8 Assembler Language Program - see page 4.1 of the PDP-8 Emulator User's Manual
/
/ Program : Add01.pal
/ Date : May 30, 1997
/
/ Desc : This program computes C = A + B
/
/-------------------------------------------
/
/ Code Section
/
*0200
/ code starts at address 0200
Main, cla cll
/ clear AC and Link
tad A
/ load A
tad B
/ add B
dca C
/ store sum at C
hlt
/ halt program
jmp Main
/ to continue - goto Main
/
/ Data Section
/
*0300
/ data starts at address 0300
A, 2
/ A equals 2
B, 3
/ B equals 3
C, 0
/ C declared
$Main
/ End of Program; Main is entry point
Type of Assembler Statements
Assembler Directives : statements that affect how assembler translates assembler language statments; e.g. *0200
Assembler Language Instructions : generate code; e.g. tad A
Storage Allocation Statements : allocate storage for data; e.g. A, 2
Comments : statements beginning with / which are ignored by assembler
General Syntax Rules
Format of a PAL instruction
[symbolic address,] opcode(s) [i] [offset] [/comment]
Appendix A from PDP-8 Emulator User's Manual: PDP-8 opcode list
Programming "Tricks"
Using the "dot" operator to perform a relative jump
isz index / add 1 to index
tad index / add index to running
sum in accumulator
isz count / add 1 to count
and skip if zero
jmp .-3 / otherwise
loop
Allocating an Array of length 10
array, 0;0;0;0;0;0;0;0;0;0;
Storing the Value of an address at that address
*0400
/ move to address 400
X, .
/ store at X it's own address
Allocating an Array of Length 10 where "array" contains the address of the first component
array, .+1;0;0;0;0;0;0;0;0;0;0
Defining a Null Terminated String
Word, 'Hello World!'; 0
Defining a Null Terminated String which ends with a Carriage Return - Line Feed combination
Word, 'Hello World!'; 13d; 10d; 0
Defining a Null Terminated String whose first word is its own address (for use with autoindexing)
Word, . ;'Hello World!'; 13d; 10d; 0
The PDP-8 Assembly Process: An assembler essentially substitutes numeric values for mnemonic code using table look-up. The simplified PDP-8 Assembler presented below does this using two tables: a pre-defined opcode table and a user-defined symbol table.
As the assembler scans each line of code, it checks the syntax of each line identifying opcodes (e.g. symbols like tad or cla cll) and user-defined symbols like Main or a which it enters into the user-defined symbol table. At the same time it keeps track of the address of the instruction using a location counter . This is used to define the value of the symbol. Often a symbol is encountered which has not been defined. This is called the forward-reference problem. One way to solve the forward-reference problem is to use a two-pass assembler. On the first pass through the code (Pass One) the assembler checks syntax and builds the user-defined symbol table. On Pass Two the assembler, using table look-up, translates the mnemonic code into machine code.
An Example
*0200
Main, cla cll
tad 1000 <- Opcode Table
tad a
isz 2000
spa sna ;skip if AC > 0
dca 3000
jmp done
...
cia
jmp 5000
tad m
...
Loop, tad b
cla 7200
isz m
cll 7100
jmp Loop
spa 7510
Done, dca c
sna 7450
hlt
cia 7041
jmp Main
hlt 7402
*0300
a, 11d
b, 12d
Main 0200 <- User Symbol Table
c, 0
Loop 0206
m, 0
Done 0211
$Main
a 0300
b 0301
c 0302
m 0303
Note that the *nnnn directive changes the value of the location
counter.
LC = 0
PassOne = True;
While PassOne Do
begin
Read Line
if Line == *<integer> then
LC = value of <integer>
else if Label (i.e. <symbol>,) detected then
begin
check syntax of Line
for either
Line == <symbol>, <opcode(s)> [i] [<expression>] or
Line == <symbol>, <expression>
add (<symbol>, LC)
pair to Symbol Table
increment LC
end
else if Line == <symbol> "=" <integer>
the
add (<symbol>, value
of <integer>) to Symbol Table
else if Line == <expression>
begin
check syntax of line
for either
Line == <opcode(s)> [i] [<expression>] or
Line == <expression>
increment LC
end
else if Line == $<symbol> then
PassOne = False;
end {PassOne}
LC = 0;
PassTwo = True
While PassTwo Do
begin
<instruction> = 0000;
Read Line
if Line is MRI instruction
begin
Get <opcode value>
from PDP-8_Symbols_Table
<instruction> = <instruction> or <opcode
value>
if indirect bit then
<instruction> = <indirection> or 0400
evaluate <expression>
using User_Symbol_Table look up
if <expression value> is on Page Zero then
<instruction> = <instruction> OR (<expression value> AND 0177)
else if <expression
value is on Current Page then
<instruction> = <instruction> OR 0200 OR (<expression value> AND
0177)
else
Report "Out of Range Error"
Deposit <instruction>
at LC
increment LC
end
else if Line is I/O Transfer Instruction
...
else if Line is Microinstruction
...
else if Line is <symbol>, <expression>
then
begin
Evaluate <expression>
using User_Symbol_Table look up
Deposit <expression
value> at LC
increment LC
end;
else if Line == *<integer>
LC = <integer>
else if Line == $<symbol>
begin
Look Up value of <symbol>
in User_Symbol_Table
Set PC = <symbol
value>
PassTwo = False;
end; {PassTwo}