PDP11 Assembler

Page content

PDP11 Assembler

This text describes how to assemble PDP11 files on Linux.

MACRO-11 assembler, linker, disassembler for Linux

There are several ways to create object binaries for PDP11 on Linux. I have tested these tools that form a nice tool set for handling PDP11 assembler files on Linux:

All tools did compile without any options by just executing make on them.

To assemble an existing MAC-File just execute

macro11 hello.mac -o hello.obj -l hello.lst

Resulting files:

-rw-r--r-- 1 dennis users  2217  2. Mai 13:55 multiecho.mac
-rw-r--r-- 1 dennis users   202  2. Mai 13:56 multiecho.obj
-rw-r--r-- 1 dennis users  4539  2. Mai 13:56 multiecho.lst

After a file was assembled, it needs to be linked. Linking means that references are relocated and resolved.

pclink11 multiecho.obj /MAP /STB /A /T:<desired target address>

The linkage process creates the executable as .SAV file. Also, a MAP file and a STB (symbol table) file can be created.

-rw-r--r-- 1 dennis users   512  2. Mai 16:45 multiecho.STB
-rw-r--r-- 1 dennis users  1024  2. Mai 16:45 multiecho.SAV
-rw-r--r-- 1 dennis users   335  2. Mai 16:45 multiecho.MAP

The SAV file is an executable. I guess it can be executed with the Operating system RT-11. For now I just disassemble the result.

pdp11dasm multiecho.SAV

This creates a .das File:

-rw-r--r-- 1 dennis users 21342  2. Mai 16:47 multiecho.SAV.das

Using bare metal code without linking

The steps above even can be done in an easier way.

If the code is written for a PDP11 without any Operating System, the link step is not required.

The assemble step then ca be done with option -e AMA. This creates absolute addresses only in LST file result. No further relocation / linking is required.

To copy the opcodes from the LST file to a target machine, I have created a tool called all2deposit. It creates a output file that can directly read in into a SIMH PDP11 simulator.

TODO: Also add code to load opcodes into a real PDP11 machine.

Programming tools, docs and helpers

Octal numbers

An octal number like 177560 or 377 looks confusing at first sight. All numbers in context of PDP11 are octal numbers; in documentation, manuals and example code. Macro11 could take also hex and decimal numbers and more, but it is better to stay on the tradition here.

Conversion on octal numbers

It is easy to do the conversion, if we use binary representation as intermediate format.

From hex to octal and octal to hex

Example 0xff (which is 255 decimal):

0xff = 1111.1111 binary = 11.111.111 = 377 in octal

This means while hexadecimal numbers group 4 bits to a digit in range 0..F, octal numbers group 3 bits to a digit in range 0..7.

Example 200 octal (which is 128 decimal):

200 octal = 10.000.000 binary = 1000.0000 = 0x80

Byte values

Each byte occupy 8 bits. Highest value possible in 8 bits is 377 octal=0xff.

Lets assume we have two bytes 012 015

This will be in PDP11 word (reversed order, due to little endian):

015 012 = 000.001.101 000.001.010 = 00.0001.1010.0000.1010 = 0x01A0A

The two bytes 012 015 will NOT result in an octal word 015012. The result is:

015 012 = 00.001.101 00.001.010 = 0.000.110 100.001.010 = 006412

From words to bytes, more examples

031061 = 0.011.001 000.110.001 = 0011.0010.0011.0001 = 3231 hex 032063 = 0.011.010 000.110.011 = 0011.0100.0011.0011 = 3433 hex

Because 31,32,33,34 are ASCII codes, the two words represent probably these characters “1”, “2”, “3”, “4”

Add

add.mac

TITLE Add two numbers
        .IDENT "V00.00"

        STACK = 0x600

        .asect
        .=1000

        .text
start:
        mov     $STACK, sp
        mov     #100, r1
        add     #100, r1

        .end  
./macro11 add.mac -o add.obj -l add.lst

add.lst

       1 000000 000000G 060000  000000G TITLE Add two numbers
         000006 000000G                 
       2                                        .IDENT "V00.00"
       3                                
       4 000000                                 STACK = 0x600
       5                                
       6                                        .asect
       7 001000                                 .=1000
       8                                
       9 001000 000000G                         .text
      10                                start:
      11 001002 016706  000000G                 mov     $STACK, sp
      12 001006 012701  000100                  mov     #100, r1
      13 001012 062701  000100                  add     #100, r1
      14                                
      15                                        .end            
      15 
@0/176377 700
@1000/016706 0
@1002/000000 16706    
@1004/177777 0
@1006/000000 12701    # mov ...,r1
@1010/177777 100      # = #100
@1012/000000 62701    # add ...,r1
@1014/177777 100      # = #100
@1016/000000 0        # HALT

@1006G                # run the code
001020
@R1/000200            # Get result from R1

Write character ‘B’ to console

Example from: https://en.wikipedia.org/wiki/On-line_Debugging_Tool#Example

TITLE B to console    
        .IDENT "V00.00"

        .asect
        .=1000

        .text

start:
        movb    #101, @#177566  
        jmp     @#1000
        halt
        
        .end

assembles to:

       1                                
       2 000000 000000G 000000G 000000G TITLE B to console    
         000006 000000G                 
       3                                        .IDENT "V00.00"
       4                                
       5                                        .asect
       6 001000                                 .=1000
       7                                
       8 001000 000000G                         .text
       9                                
      10                                start:
      11 001002 112737  000101  177566          movb    #101, @#177566  
      12 001010 000137  001000                  jmp     @#1000
      13 001014 000000                          halt
      14                                
      15                                        .end            
      15 

Execute the program, needs to be interrupted with HALT switch.

@
000000
@1000/177777 112737
@1002/041604 102
@1004/177777 177566
@1006/041620 137
@1010/137377 1000

@1000GBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB...