# A Simple Computer

Believe it or not, there is a huge advantage in studying a very simple computer before diving into the not-very-simple i7.

## Basic Components

This is going to be really simple. Our computer will have:

• A 32-bit register, called the accumulator ($A$).
• A 32-bit register, called the instruction pointer ($IP$).
• 256Mi words of memory, each 32-bits wide ($M[\bullet]$).
• Up to 256Mi ports ($P[\bullet]$).

## Operation

At each “step”, the computer reads the memory word whose address is in $IP$ and then increments $IP$. Then it carries out the instruction that that word represents.

This is how most computers, uh, cores, work. It is called the fetch-execute cycle.

In this class, we’re not too concerned with how steps are synchronized; we’ll just say there’s a clock.

## The Instructions

Each word that the computer tries to execute will be interpreted to have:

• The first 4 bits as the opcode.
• The remaining 28 bits will refer to a memory address or port number.

For a given instruction word, let’s call $op$ the first four bits, and $x$ the last 28 bits. We formally specify the operation of each instruction as follows. All arithmetic is signed, modular, 32-bit integer arithmetic.

opActionRemarks
0$A := M[x]$Load accumulator from memory
1$M[x] := A$Store accumulator to memory
2$A := P[x]$Read from a port into the accumulator
3$P[x] := A$Write accumulator out to a port
4$A := A + M[x]$Add into accumulator
5$A := A - M[x]$Subtract from accumulator
6$A := A \times M[x]$Multiply into accumulator
7$A := A \div M[x]$Divide accumulator
8$A := A \:\texttt{mod}\: M[x]$Modulo
9$A := A \wedge M[x]$Bitwise AND
A$A := A \vee M[x]$Bitwise OR
B$A := A \oplus M[x]$Bitwise XOR
C$IP := x$Jump to new address
Dif $A = 0$ then $IP := x$Jump if accumulator is zero
Eif $A < 0$ then $IP := x$Jump if accumulator is less than zero
Fif $A > 0$ then $IP := x$Jump if accumulator is greater than zero

## An Example Program

This program, when loaded into memory at address 0, outputs powers of two, starting with 1, and going just past 1,000,000, to port 100 (64 hex):

C0000003
00000001
000F4240
00000001
30000064
40000001
10000001
50000002
E0000003
C0000009

Exercise: Write a program for this computer to generate the first 10 fibonacci numbers to port 7.
Exercise: Write a program for this computer to output Hello, world to port 888, assuming a UTF-32 encoding.
Exercise: Write, in the language of your choice, an interpreter for this computer. You will have to make a number of decisions regarding the user interface. Be creative.

## Assembly Language

The example above was hard to read. Just listing the contents of memory that the processor executes is called “writing machine language.” Let’s use mnemonics for each instruction. Then the example becomes:

 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009  C0000003 00000001 000F4240 00000001 30000064 40000001 10000001 50000002 E0000003 C0000009   JUMP start ; begin by jumping over the data area pow: 1 ; store the current power value here limit: 1000000 ; we'll be computing powers up to this amount start: LOAD pow ; bring the value into accumulator to use OUT 100 ; output the current power ADD pow ; adding to itself makes the next power! STORE pow ; store it (for next time) SUB limit ; we need to compare with limit, subtracting helps JLZ start ; if not yet past limit, keep going end: JUMP end ; this "stops" the program! 

In general, each line of an assembly language program contains:

• An optional label (so you don't have to memorize physical addresses)
• Either
• A data value
• An instruction and its operands. An operand can be a direct value or a label. (Labels are just convenient shorthands for values anyway.)
• Comments, beginning with the ; character.

In our machine, the mnemonics will be: LOAD, STORE, IN, OUT, ADD, SUB, MUL, DIV, MOD, AND, OR, XOR, JUMP, JZ, JLZ, JGZ.

The process of converting from assembly language to machine language is called assembly. The reverse process is called disassembly. Yes, there exist programs called assemblers and disassemblers.

Exercise: Write an assembler for this computer. Consider writing it in JavaScript as a browser-based app, so that as you type assembly language in one window you immediately see the machine language in another.
Exercise: Suppose you were disassembling the word 100038A0. Is this an instruction to store the accumulator into memory address 0x00038A0, or is it a representation of the value 268449952? Or is it both? Why is this question philosophically interesting? Discuss.

## What We Did Not Cover

The purpose of this simple computer is to introduce the basic concepts of the fetch-execute cycle and the difference between machine and assembly language. Things we haven’t covered include:

• How does the program get into memory?
• How do we start the instruction pointer at 0?
• How do we write an assembler?
• What is an operating system?
• Can I run Java on this thing?

## Moving On

If you found this machine interesting, here are things you can do: