===================================================== LMC Sample Program #7 - subroutine call/return and linkage ===================================================== - Ian! D. Allen - idallen@idallen.ca - www.idallen.com ============================================================================= 7A: LMC Subroutine CALL/return Example -------------------------------------- Let's write a program that reads numbers from the input and outputs the double and quadruple of each number. The program will stop when it reads the input number 000. We will code this as two separate source files: a MAIN program and a Double subroutine that takes one input argument and returns the double of the number in the LMC Calculator. We choose to pass our argument to the subroutine by using a memory location to store it. (Real-world subroutine linkage usually puts arguments on the stack or in registers.) The return value from the subroutine is placed in the LMC calculator. The input argument is not modified. Here is the pseudocode for the two modules: // MAIN program loop { input num if ( num == 000 ) break doub = Double(num) output doub quad = Double(doub) output quad } stop // Double subroutine subroutine Double(arg) { return arg+arg } ; main program LOOP IN ; input num STO NUM LDA NUM ; if ( num == 000 ) break SUB ZERO SKNZ ; skip *into* loop body if NUM is not zero JMP BREAK LDA NUM ; doub = Double(num) STO ARG CALL DOUBLE STO DOUB LDA DOUB ; output doub OUT LDA DOUB ; quad = Double(doub) STO ARG CALL DOUBLE STO QUAD LDA QUAD ; output quad OUT JMP LOOP BREAK HLT NUM DAT ; variable DOUB DAT ; variable QUAD DAT ; variable ZERO DAT 000 ; constant ; Double subroutine ; ARG - input argument ; returns double the input using LMC Calculator ARG DAT ; input argument must be stored here first RETURN DAT ; space for CALL return value DOUBLE LDA ARG ; return arg+arg ADD ARG JMP RETURN ============================================================================= 7B: LMC Subroutine call-return argument Example ----------------------------------------------- This is the same basic algorithm as the previous example, but instead of returning the value in the LMC calculator, the subroutine argument is a call-return argument that is itself modified to contain the return value: // MAIN program loop { input num if ( num == 000 ) break Double(num) // call-return argument is modified by subroutine output num Double(num) // call-return argument is modified by subroutine output num } stop // Double subroutine with call-return argument subroutine Double(CALLRETURN arg) { arg = arg+arg // call-return argument is itself modified } ; main program LOOP IN ; input num STO NUM LDA NUM ; if ( num == 000 ) break SUB ZERO SKNZ ; skip *into* loop body if NUM is not zero JMP BREAK LDA NUM ; Double(num) *** num is a call-return argument *** STO ARG CALL DOUBLE LDA ARG ; *** pick up modified call-return argument *** STO NUM LDA NUM ; output num OUT LDA NUM ; Double(num) STO ARG CALL DOUBLE LDA ARG ; pick up modified call-return argument STO NUM LDA NUM ; output num OUT JMP LOOP BREAK HLT NUM DAT ; variable ZERO DAT 000 ; constant ; Double subroutine ; ARG - input and output argument (call-return parameter) ; returns double the input by modifying the input argument ARG DAT ; input/output argument must be stored here first RETURN DAT ; space for CALL return value DOUBLE LDA ARG ; arg = arg+arg ADD ARG STO ARG ; subroutine modifies input argument with answer JMP RETURN -- | Ian! D. Allen - idallen@idallen.ca - Ottawa, Ontario, Canada | Home Page: http://idallen.com/ Contact Improv: http://contactimprov.ca/ | College professor (Free/Libre GNU+Linux) at: http://teaching.idallen.com/ | Defend digital freedom: http://eff.org/ and have fun: http://fools.ca/