TAOCP 5 Exercise 7
The following MIXAL subroutine `COMPARE` implements multiprecision lexicographic comparison of two sequences of words stored at `A+1 … A+n` and `B+1 … B+n`, where `n ≥ 1` is given in `rI1`.
Section 5: Introduction to Sorting
Exercise 7. [17] Write a MIX subroutine for multiprecision comparison of keys, having the following specifications:
Calling sequence: JMP COMPARE
Entry conditions: $\mathtt{r1} = n$; $\mathtt{CONTENTS}(\mathtt{A} + k) = a_k$ and $\mathtt{CONTENTS}(\mathtt{B} + k) = b_k$, for $1 \le k \le n$; assume that $n \ge 1$.
Exit conditions: $\mathtt{CI} = \mathtt{GREATER}$, if $(a_n, \ldots, a_1) > (b_n, \ldots, b_1)$; $\mathtt{CI} = \mathtt{EQUAL}$, if $(a_n, \ldots, a_1) = (b_n, \ldots, b_1)$; $\mathtt{CI} = \mathtt{LESS}$, if $(a_n, \ldots, a_1) < (b_n, \ldots, b_1)$; $\mathtt{rX}$ and $\mathtt{rI1}$ are possibly affected.
Here the relation $(a_n, \ldots, a_1) < (b_n, \ldots, b_1)$ denotes lexicographic ordering from left to right; that is, there is an index $j$ such that $a_k = b_k$ for $n \ge k > j$, but $a_j < b_j$.
Verified: yes
Solve time: 31m04s
Solution
The following MIXAL subroutine COMPARE implements multiprecision lexicographic comparison of two sequences of words stored at A+1 … A+n and B+1 … B+n, where n ≥ 1 is given in rI1. The comparison proceeds from the most significant word (k = n) down to the least significant (k = 1). The comparison indicator CI is set to GREATER, EQUAL, or LESS according to the first differing word; if all words are equal, CI becomes EQUAL. The subroutine uses rA for loading words and modifies rI1 (which becomes zero on exit); rX is untouched but allowed to be affected per the specification. All other registers (rA, rI2-rI6, rJ) are preserved.
The calling sequence given in the exercise is JMP COMPARE. For the subroutine to return correctly, the caller must place the return address in rJ before executing the JMP (this is the standard convention when a JMP is used for subroutine linkage instead of JSJ). The subroutine returns with JMP *, which uses rJ.
COMPARE START 0
STA SAVEA ; preserve rA
1H LDA A,1 ; load a_k (k = rI1)
CMPA B,1 ; compare with b_k (sets CI)
JNE 2F ; if CI ≠ EQUAL, exit immediately
DEC1 1 ; k := k - 1
J1P 1B ; if k > 0, repeat loop
2H LDA SAVEA ; restore rA
JMP * ; return to caller (rJ holds return address)
SAVEA CON 0
END COMPARE
Explanation
- Entry:
rI1 = n(the number of words,n ≥ 1). The base addressesAandBare defined externally. The caller must have setrJto the return address before executingJMP COMPARE. - Register preservation:
rAis saved inSAVEAat the start and restored just before return.rXis not used;rI2-rI6andrJare untouched.rI1is decremented to zero (explicitly allowed to be affected). - Loop invariant: At the start of each iteration,
rI1 = kwherekis the current index (initiallyn, thenn‑1, …,1). All words with index> khave been compared and found equal. - Body:
LDA A,1loadsa_kintorA;CMPA B,1compares it withb_k, settingCItoGREATERifa_k > b_k,EQUALif equal,LESSifa_k < b_k. - Early exit:
JNE 2Fjumps to the common exit point whenCI ≠ EQUAL; the correct indicator is already inCI. - Loop control: If the words are equal,
DEC1 1decrements the index.J1P 1Brepeats the loop whilerI1 > 0. BecauserI1starts atn ≥ 1and is decremented by1each iteration, the loop executes exactlyntimes. WhenrI1becomes0,J1Pfails and control falls through to2H. - Exit: At
2H,rAis restored fromSAVEA(this instruction does not affectCI).JMP *returns to the caller using the address inrJ.CIretains the value set by the lastCMPA(either the first non‑equal comparison orEQUALafter the final iteration).
Verification
- Boundary case
n = 1: The loop executes once. Ifa_1 = b_1,DEC1makesrI1 = 0,J1Pfalls through, andCI = EQUAL. Ifa_1 ≠ b_1,JNEjumps to2HwithCIreflecting the inequality. Correct. - All words equal: After
niterationsrI1 = 0; the finalCMPAsetCI = EQUAL. No subsequent instruction altersCI. Correct. - First difference at
k = j: The loop runs fork = n, n‑1, …, j+1(all equal), then atk = jtheCMPAsetsCIto the appropriate non‑EQUALvalue,JNEexits, andCIis preserved. Correct. - Register usage: Only
rA,rI1, andCIare modified during the loop;rAis restored before return.rXis never used (allowed to be affected).rI2-rI6andrJare untouched. The code respects the given specifications.
This completes the proof. ∎