MIXAL

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".

<<find_max.mal>>=
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.

<<find_max.c>>=
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".

<<500primes.mal>>=
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).

<<primes500.c>>=
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;
    }
}