TAOCP 1.4.2 Exercise 5
In the coroutine linkage of §1.
Exercise 5. [15] Suppose both coroutines IN and OUT want the contents of register A to remain untouched between exit and entry; in other words, assume that wherever the instruction JMP IN occurs within OUT, the contents of register A are to be unchanged when control returns to the next line, and make a similar assumption about JMP OUT within IN. What coroutine linkage is needed? (Compare with (4).)
Verified: no
Solve time: 4m37s
Solution
In the coroutine linkage of §1.4.2,
OUT STJ IN
JMP OUT1
IN STJ OUT
JMP IN1
the locations IN and OUT are not fixed entry points. They are modified by STJ, so that a later JMP IN or JMP OUT resumes the suspended coroutine at the proper continuation point.
To preserve register $A$, each coroutine must have its own saved value of $A$. When a coroutine yields control, its current value of $A$ must be saved. When that coroutine is later resumed, the saved value must be restored before execution continues.
The restoration must therefore be incorporated into the continuation mechanism itself.
Let AIN and AOUT be memory cells containing the saved values of $A$ for coroutines IN and OUT, respectively. Replace the linkage by
OUT STA AOUT
STJ OUTRET
JMP OUT1
OUTRET LDA AOUT
JMP *
IN STA AIN
STJ INRET
JMP IN1
INRET LDA AIN
JMP *
AIN CON 0
AOUT CON 0
Here OUTRET and INRET are the locations used in the coroutine linkage. The instruction STJ OUTRET stores the return address into the address field of the instruction at OUTRET; similarly STJ INRET stores a return address into INRET.
To see how this works, suppose IN executes JMP OUT with $A=a$.
- Control enters
OUT. STA AOUTsaves the value $a$ belonging to the suspended coroutineIN's partner, namely the coroutine being entered will later need its own value preserved.STJ OUTRETrecords the continuation point ofINin the usual coroutine manner.JMP OUT1begins or resumes execution ofOUT.
Now suppose later OUT executes JMP IN with $A=b$.
- Control enters
IN. STA AINsaves the value $b$ associated withOUT.STJ INRETrecords the continuation point ofOUT.JMP IN1transfers to the address currently stored in locationIN.
But location IN was previously modified by STJ OUTRET. Hence control returns to
OUTRET LDA AOUT
JMP *
The instruction LDA AOUT restores the value of $A$ that belonged to OUT when it last yielded control. The following JMP * then jumps to the continuation address that STJ OUTRET placed into the instruction.
Thus OUT resumes exactly where it left off, with the same contents of register $A$.
The argument for IN is symmetric. When IN is later resumed, execution first reaches
INRET LDA AIN
JMP *
which restores the value of $A$ that IN had when it previously yielded control, and then continues at the recorded return address.
Therefore the required coroutine linkage is obtained by replacing each return location with a two-instruction sequence
RET LDA saved_A
JMP *
and arranging that each coroutine saves its own value of $A$ before yielding. This preserves register $A$ across every JMP IN and JMP OUT, while retaining the normal coroutine return mechanism.