difficult to use ROM with the PDP-8 because read-write return-address storage is commingled with read-only code storage in the address space. Programs intended to be placed into ROMs approach this problem in several ways: They copy themselves to read-write memory before execution, or They are placed into special ROM cards that provide a few words of read/write memory, accessed indirectly through the use of a thirteenth flag bit in each ROM word. They avoid the use of subroutines; or use code such as the following, instead of the JMS instruction, to put the return address in read-write memory: JUMPL, DCA TEMP / Deposit the accumulator in some temporary location TAD JUMPL+3 / Load the return address into the accumulator: hard coded JMP SUBRO / Go to the subroutine, and have it handle jumping back (to JUMPL+3) The use of the JMS instruction makes debugging difficult. If a programmer makes the mistake of having a subroutine call itself, directly or by an intermediate subroutine, then the return address for the outer call is destroyed by the return address of the subsequent call, leading to an infinite loop. If one module is coded with an incorrect or obsolete address for a subroutine, it would not just fail to execute the entire code sequence of the subroutine, it might modify a word of the subroutine's code, depositing a return address that the processor might interpret as an instruction during a subsequent correct call to the subroutine. Both types of error might become evident during the execution of code that was written correctly. Software stack Though the PDP-8 does not have a hardware stack, stacks can be implemented in software. Here are example PUSH and POP subroutines, simplified to omit issues such as testing for stack overflow and underflow: *100 /make routines accessible for next example PUSH, 0 DCA DATA CLA CMA / -1 TAD SP DCA SP TAD DATA DCA I SP JMP I PUSH /Return POP, 0 CLA CLL TAD I SP ISZ SP JMP I POP DATA, 0 SP, 0 And here is "Hello World" with this "stack" implemented, and "OUT" subroutine: *200 MAIN, CLA CLL /Set the message pointer TAD (MESSG /To the beginning of the message (literal) DCA SP LOOP, JMS POP SNA /Stop execution if zero HLT JMS OUT /Otherwise, output a character JMP LOOP MESSG, "H "e "l "l "o ", " "w "o "r "l "d