ORG $0 DC.L $8000 stack pointer value after a reset DC.L START program counter value after a reset START: MOVE.L #1,-(SP) put 1 into arg. frame for F MOVE.L #2,-(SP) put 2 into arg. frame for F MOVE.L #20,-(SP) put 20 into arg. frame for F LEA.L $0,A6 initialize frame pointer * (there is no higher arg. frame yet) JSR F call F( 1, 2, 20) MOVE.L (SP)+,D0 put result into D0 BREAK ******************************************************************************** * * function: (SP1) F( (SP1), (SP2), (SP3)) * * description: * Expects an argument frame with three arguments on the stack. * The register A6 should contain the frame pointer of the actual environment. * * registers affected: none * F: LINK A6,#0 store pointer to arg. frame in A6 MOVEM.L D0-D2,-(SP) save registers MOVE.L 16(A6),D0 fetch u from actual arg. frame MOVE.L 12(A6),D1 fetch v from actual arg. frame MOVE.L 8(A6),D2 fetch n from actual arg. frame SUBI.L #1,D2 n = n - 1 MOVE.L D1,-(SP) put v into arg. frame for G MOVE.L D0,-(SP) put u into arg. frame for G MOVE.L D2,-(SP) put n into arg. frame for G * no frame pointer adjustment needed JSR G call G( v, u, n) MOVE.L (SP)+,D0 put result into D0 MOVE.L D0,16(A6) write result into arg. frame (1st entry) MOVEM.L (SP)+,D0-D2 restore registers UNLK A6 restore A6 MOVE.L (SP),8(SP) kill last two entries of arg. frame: ADDQ.L #8,SP move return address, adjust SP RTS ******************************************************************************** * * function: (SP1) G( (SP1), (SP2), (SP3)) * * description: * Expects an argument frame with three arguments on the stack. * The register A6 should contain the frame pointer of the actual environment. * * registers affected: none * G: LINK A6,#0 store pointer to arg. frame in A6 MOVEM.L D0-D4,-(SP) save registers MOVE.L 16(A6),D0 fetch w from actual arg. frame MOVE.L 12(A6),D1 fetch z from actual arg. frame MOVE.L 8(A6),D2 fetch n from actual arg. frame MOVEA.L (A6),A0 fetch pointer to arg. frame of F MOVE.L 16(A0),D3 fetch u from arg. frame of F MOVE.L 12(A0),D4 fetch v from arg. frame of F CMPI.L #0,D2 (n == 0) ? BLE G_TAIL SUBI.L #1,D2 n = n - 1 CMP.L D3,D0 (w > u) ? BGT G_G G_F: ADDI.L #1,D0 w = w + 1 MOVE.L A6,-(SP) save A6 MOVE.L D4,-(SP) put v into arg. frame for F MOVE.L D0,-(SP) put w into arg. frame for F MOVE.L D2,-(SP) put n into arg. frame for F MOVEA.L (A6),A6 adjust frame pointer for F MOVEA.L (A6),A6 adjust frame pointer for F JSR F call F( v, w, n) MOVE.L (SP)+,D0 res = F( ...) MOVE.L (SP)+,A6 restore A6 JMP G_END G_G: SUBI.L #1,D3 u = u - 1 MOVE.L A6,-(SP) save A6 MOVE.L D3,-(SP) put u into arg. frame for G MOVE.L D1,-(SP) put z into arg. frame for G MOVE.L D2,-(SP) put n into arg. frame for G MOVEA.L (A6),A6 adjust frame pointer for G JSR G call G( u, z, n) MOVE.L (SP)+,D0 res = G( ...) MOVE.L (SP)+,A6 restore A6 JMP G_END G_TAIL: ADD.L D1,D0 res = w + z G_END: MOVE.L D0,16(A6) write result into arg. frame (1st entry) MOVEM.L (SP)+,D0-D4 restore registers UNLK A6 restore A6 MOVE.L (SP),8(SP) kill last two entries of arg. frame: ADDQ.L #8,SP move return address, adjust SP RTS ******************************************************************************** END