======================
LMC Indirection Tricks
======================
-Ian! D. Allen - idallen@idallen.ca - www.idallen.com
The LMC has no "indirect addressing" mode, where you can tell the LMC to
load or store via an address that changes according to the program logic.
For example: read in numbers and store them in increasing memory locations
starting at the address of the first number read. Most real computers
have some "address register" that you can increment and use; the LMC
does not. All LMC load and store operations use a fixed address as
the operand.
The trick you have to use in the LMC to load or store at a
program-determined address is to write "self-modifying code": the
program logic must modify a "LDA" or STO" instruction to contain the
program-determined address and the LMC must then execute that modified
instruction to do the actual load or store. The program must continually
modify the load or store instruction by updating the address.
Here is an example algorithm that uses this trick twice:
Write the values 11 through 29 into mailboxes 81 through 99.
Sum the mailboxes in reverse order; output the sum.
LMC Pseudocode
for ( counter = 81; counter <= 99; counter++ )
memory[counter] = counter - 70
endfor
sum = 0
for ( counter = 99; counter >= 81; counter-- )
sum += memory[counter]
endfor
output sum
Revised Pseudocode (turn FOR into WHILE)
counter = 81
while ( counter <= 99 )
memory[counter] = counter - 70
counter = counter + 1
endwhile
sum = 0
counter = 99
while ( counter >= 81 )
sum += memory[counter]
counter = counter - 1
endwhile
output sum
;Label Mnem. Operand Comments.............
;----- ----- ------- ---------------------
LDA NUM81
STO COUNTER
TEST1 LDA NUM99 ; FIRST LOOP while counter <= 99
SUB COUNTER
SKP
JMP ENDWH1
LDA STORE ; mem[counter] = counter - 70
ADD COUNTER
STO DOIT1
LDA COUNTER
SUB NUM70
DOIT1 DAT ? ; SELF-MODIFYING "STO" CODE HERE
LDA COUNTER ; counter++
ADD ONE
STO COUNTER
JMP TEST1
ENDWH1 LDA ZERO ; two initializations in FOR loop
STO SUM
LDA NUM99
STO COUNTER
TEST2 LDA COUNTER ; SECOND LOOP while counter >= 81
SUB NUM81
SKP
JMP ENDWH2
LDA LOAD ; sum += mem[counter]
ADD COUNTER
STO DOIT2
DOIT2 DAT ? ; SELF-MODIFYING "LDA" CODE HERE
ADD SUM
STO SUM
LDA COUNTER ; counter--
SUB ONE
STO COUNTER
JMP TEST2
ENDWH2 LDA SUM ; output sum and stop
OUT
HLT
; CONSTANTS
LOAD DAT 100 ; code for a LOAD
STORE DAT 200 ; code for a STORE
ONE DAT 001
NUM70 DAT 070
NUM81 DAT 081
NUM99 DAT 099
; VARIABLES
SUM DAT ? ; sum of mailboxes
COUNTER DAT ? ; count the mailboxes