Saturday, October 29, 2011

Learning Assembly Language, Part 2: Little Man Computer

Last time we discussed the CARDIAC assembly language. We did everything by hand. It was also incredibly limited.

This time, we will introduce a more comprehensive assembly language which is also done completely by hand.

The architecture is known as the "Little Man Computer", it too is in decimal (base-10).

The little man computer is a model designed to assist in the understanding of the fetch/execute cycle, through the visualization of elements of the computer architecture that would normally remain hidden.

The story is the suppose we have a "little man" trapped in a room with 100 mailboxes.

We also have two mailboxes at the other end labelled INBOX and OUTBOX which are used for receiving and outputting data to the outside world.

In the center of the room, there is a work area containing a simple two function (addition and subtraction) calculator known as the Accumulator and a reset-able counter known as the Program Counter.

Architecture Specifications

So, we have 100 memory cells (the mailboxes) each can contain 3-digit numbers from -999 to +999.

The basic algorithm for the instruction cycle is given by:
  1. check the Program Counter for the mailbox number that contains a program instruction
  2. fetch the instruction from the mailbox with that number
  3. Increment the Program Counter (so that it contains the mailbox number of the next instruction)
  4. decode the instruction (includes finding the mailbox number for the data it will work on)
  5. fetch the data from the mailbox with the number found in the previous step
  6. execute the instruction
  7. store the new data in the mailbox from which the old data was retrieved
  8. Repeat the cycle or halt
Now what are the instructions?

As with the CARDIAC system, an instruction looks like OAA where the first digit specifies the opcode (the operation to be carried out) and AA contain the address which we need to work with.

There are roughly 10 operations for the little man computer, similar to the CARDIAC system.

In general, any assembly language will have a similar grouping of instructions into several families:
  1. Arithmetic: arithmetic instructions may operate on all registers or on just a special register (e.g. accumulator).
  2. Control: stuff like "copy contents of register 1 into register 2", loading to and storing from the accumulator, "jumps" like "goto", etc.
  3. Register-addressing method: these are indirectly loading values into registers, very important for theoretical computer scientists...not so important a distinction for the working coder.
  4. Input-output: usually present in all models.

Now, let us list off the instructions for the little man computer (taken from wikipedia).

Table of Little Man Instructions
Numeric code Mnemonic code Instruction Description
1xx ADD ADD Add the value stored in mailbox xx to whatever value is currently on the accumulator (calculator).
Note: the contents of the mailbox are not changed, and the actions of the accumulator (calculator) are not defined for add instructions that cause sums larger than 3 digits.
2xx SUB SUBTRACT Subtract the value stored in mailbox xx from whatever value is currently on the accumulator (calculator).

Note: the contents of the mailbox are not changed, and the actions of the accumulator are not defined for subtract instructions that cause negative results - however, a negative flag will be set so that 8xx (BRP) can be used properly.
3xx STA STORE Store the contents of the accumulator in mailbox xx (destructive).

Note: the contents of the accumulator (calculator) are not changed (non-destructive), but contents of mailbox are replaced regardless of what was in there (destructive)
5xx LDA LOAD Load the value from mailbox xx (non-destructive) and enter it in the accumulator (destructive).
6xx BRA BRANCH (unconditional) Set the program counter to the given address (value xx). That is, value xx will be the next instruction executed.
7xx BRZ BRANCH IF ZERO (conditional) If the accumulator (calculator) contains the value 000, set the program counter to the value xx. Otherwise, do nothing.
Note: since the program is stored in memory, data and program instructions all have the same address/location format.
8xx BRP BRANCH IF POSITIVE (conditional) If the accumulator (calculator) is 0 or positive, set the program counter to the value xx. Otherwise, do nothing.
Note: since the program is stored in memory, data and program instructions all have the same address/location format.
901 INP INPUT Go to the INBOX, fetch the value from the user, and put it in the accumulator (calculator)
Note: this will overwrite whatever value was in the accumulator (destructive)
902 OUT OUTPUT Copy the value from the accumulator (calculator) to the OUTBOX.
Note: the contents of the accumulator are not changed (non-destructive).
000 HLT HALT Stop working.
DAT DATA This is an assembler instruction which simply loads the value into the next available mailbox. DAT can also be used in conjunction with labels to declare variables. For example, DAT 984 will store the value 984 into a mailbox.

Mnemonics

In the Little man computer, there are these exotic things called "mnemonics". It works sort of like macros in C/C++...but not really.

For example, we could refer to data locations using mnenomics:
INP
STA FIRST 
INP
STA SECOND 
LDA FIRST 
SUB SECOND
OUT
HLT
FIRST DAT
SECOND DAT
The STA FIRST uses FIRST as-a mnenomic, and it is defined as-a DAT.

In short, a mnemonic is a short sequence of characters (e.g. FIRST or SECOND) that are an alias for an opcode (e.g. DAT).

Labels

This is the last innovative feature which differentiates Little Man from CARDIAC. We use labels to indicate portions of our program...you could think of this sort of like defining procedures.

Well, to be more precise, a label can be used to identify a particular instruction as a target for a BRANCH instruction ("where the procedure begins").

We can do more! We can also have "variables", that is associate data to a sequence of characters. We have seen this with the FIRST and SECOND example code.

An example program:
     INP
LOOP SUB ONE  // This address will be called LOOP, 
              // Subtract the value stored at ONE
     OUT
     BRZ QUIT // If we are at 0, then jump to the location QUIT
     BRA LOOP // We are not at 0, go back to the start of LOOP
QUIT HLT
ONE  DAT 1    // Put the value 1 in this mailbox,
              // and call it ONE (variable declaration)
Now what are some exercises?

Exercises

  1. Write a program that finds the first 100 prime numbers.
  2. Modify this program to take a positive number from the user n, and find the first n prime numbers.
  3. Implement a mul procedure to multiply integers together.
  4. Write up code to implement a floating point arithmetic division procedure (see Donald Knuth's Art of Computer Programming vol. 2 for details).
  5. Write a procedure to write a given number in a given base (e.g. write 720 in base 3).

Future Directions

Maybe next time I will begin discussing the MIXAL, the MIX assembly language designed by Donald Knuth.

No comments: