====================== 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