MIXAL
MIXAL is the MIX assembly language.
MIXAL operations
Roughly in the order presented in TAOCP. Refer to the book for more detail.
MIXAL has nearly 150 different operations that fit into a few simple patterns that can be (hopefully) easily remembered.
Loading Operations
LDA: Load A.
LDX: Load X.
LDi: Load rLi.
LDAN: Load A negative.
LDXN: Load X negative.
LDiN: Load i negative.
Storing Operations
STA: store A.
STX: store X.
STi: store i.
STJ: store J.
STZ: store zero.
Arithmetic Operators
ADD: add.
SUB: subtract.
MUL: multiply.
DIV: divide.
Address Transfer Operators
ENTA: Enter A.
ENTX: Enter X.
ENTi: Enter i.
ENNA: Enter negative A.
ENNX: Enter negative X.
ENNi: Enter negative i.
INCA: Increase A.
INCX: Increase X.
INCi: Increase i.
DECA: Decrease A.
DECX: Decrease X.
DECi: Decrease i.
Comparison Operators
CMPA: Compare A.
CMPX: Compare X.
CMPi: Compare i.
Jump Operators
JMP: Jump.
JSJ: Jump, save J.
JOV: Jump on overflow.
JNOV: Jump on no overflow.
JL, JE, JG, JGE, JNE, JLE: Jump on less, equal, greater, greater-or-equal, unequal, less-or-equal.
JAN, JAZ, JAP, JANN, JANZ, JANP: Jump A negative, zero, positive, nonnegative, nonzero, nonpositive.
JXN, JXZ, JXP, JXNN, JXNZ, JXNP: Jump X negative, zero, positive, nonnegative, nonzero, nonpositive.
JiN, JiZ, JiP, JiNN, JiNZ, JiNP: Jump i negative, zero, positive, nonnegative, nonzero, nonpositive.
Miscellaneous Operators
SLA, SRA, SLAX, SRAX, SLC, SRC: shift left A, shift right A, shift left AX, shift right AX, shift left AX circularly, shift right AX circularly.
MOVE
NOP: No operation.
HLT: Halt.
Input/Output Operators
IN: input.
OUT: output.
IOC: input-output control.
JRED: Jump ready.
JBUS: Jump Busy.
Conversion Operators
NUM: convert to numeric.
CHAR: convert to characters.
Pseudo-Operators in MIXAL
These are operations that appear in MIXAL, but not in MIX.
EQU: Equivalent. The following code makes X
equivalent
to 1000:
X EQU 1000
ORIG: Lines following this operation should be chosen sequentially with a starting offset (such as 3000):
ORIG 3000
Sample: Find The Maximum
First sample program. AKA Program "m".
X EQU 1000
ORIG 3000
MAXIMUM STJ EXIT
INIT ENT3 0,1
JMP CHANGEM
LOOP CMPA X,3
JGE *+3
CHANGEM ENT2 0,2
LDA X,3
DEC3 1
J3P LOOP
EXIT JMP *
Here it is converted to C code below. The function
findmax
preserves the original MIXAl control flow using
goto statements,
while the second version findmaxv2
converts it into
more conventional C control flow.
void findmax(int *x, int n, int *mp, int *jp)
{
int k, j, m;
k = n;
goto CHANGEM;
LOOP:
/* original program uses relative
* instruction jumping not available in C. */
if (m >= x[k - 1]) goto M5;
CHANGEM:
j = k;
m = x[k - 1]; /* zero indexed */
M5:
k--;
if (k) goto LOOP;
*mp = m;
*jp = j--; /* zero indexed */
}
void findmaxv2(int *x, int n, int *mp, int *jp)
{
int k, j, m;
for (k = n, j = n; k > 0; k--) {
if (m < x[k - 1]) {
j = k;
m = x[k - 1];
}
}
*mp = m;
*jp = j--;
}
Sample: Print 500 Primes
Extracted from TAOCP volume 1. It has been written in "a slightly clumsy fashion in order to illustrate most fo the features of MIXAL in a single program".
L EQU 500
PRINTER EQU 18
PRIME EQU -1
BUF0 EQU 2000
BUF1 EQU BUF0+25
ORIG 3000
START IOC 0(PRINTER)
LD1 =1- L=
LD2 =3=
2H INC1 1
ST2 PRIME+1, L
J1Z 2F
4H INC2 2
ENT3 2
6H ENTA 0
ENTX 0,2
DIV PRIME,3
JXZ 4B
CMPA PRIME, 3
INC3 1
JG 6B
JMP 2B
2H OUT TITLE(PRINTER)
ENT4 BUF1 + 10
ENT5 -50
2H INC5 L + 1
4H LDA PRIME,5
CHAR
STX 0,4(1:4)
DEC4 1
DEC5 50
J5P RB
OUT 0,4(PRINTER)
LD4 24,4
J5N 2B
HLT
ORIG PRIME+1
CON 2
ORIG BUF0-5
TITLE ALF FIRST
ALF FIVE
ALF HUND
ALF RED P
ALF PRIMES
ORIG BUF0+24
CON BUF1+10
ORIG BUF1+24
CON BUF0+10
END
The prime number finder bits of algorithm has been
converted to C code, as seen below (printing bits
are ignored for now). Like
findmax
, the control flow
has been written to closely match that of the original
MIX program, with a few tweaks (instead of indexing
towards zero, zero-indexing is used).
void primes500(int *prime)
{
int n; /* rI2 */
int k; /* rI3 */
int j; /* rI1 */
n = 3;
j = 0;
prime[j] = 2;
P2: /* N is prime. J <- J + 1 */
j++;
prime[j] = n;
P3: /* 500 found? */
if (j > 500) return;
P4: /* Advance N by 2 */
n+=2;
P5: /* k <- 2 */
k = 1;
P6: /* PRIME[k]\N? */
if ((n % prime[k]) == 0) goto P4;
P7: /* PRIME[k] too large? */
if ((n / prime[k]) > prime[k]) {
k++;
goto P6;
} else {
goto P2;
}
}