Simulated Toy Machine
Architecture for projects for Computer Systems Organization II, section 1.
The Simulated Toy Machine (STM) is a simulation of an extremely simple
machine architecture, which we will use for programming assignments 1-3.
These projects involve extending the operating system for this toy machine.
Warning: There is one very misleading aspect to this toy machine,
as compared to real machines.
Unlike any conceivable real operating system (and also unlike the Nachos
simulated machine used in the honors section), the "operating system"
for STM is not resident in the simulated machine; rather, it
is part of the simulator. This is why, for instance, the STM
does not need interrupts; in effect, control reverts to the "operating
system" after every instruction.
It is critical to keep this difference
in mind when you try to relate your experiences in programming the STM
to the running of real operating systems.
There are also, of course, numerous other unrealistic aspects to the STM;
for instance, we make no attempt to model blocking a process for I/O.
The basic architecture of the STM contains
- 1 Meg of RAM, organized as an 18 bit address space with 4 byte words.
- 16 user addressible registers. R0 is the program counter.
- A base and limit register, to support address translations with
variable length partitions. User processes can neither read nor write
the base and limit registers.
Machine language --- STML
Strictly speaking, there's actually no need for you to care about
the structure of STML. You're not
going to have to write code in STML, and the code to execute STML
instructions is all provided for you. This is just here for the sake
Each instruction in STML is a 32-bit word, organized as follows: (bits
are numbered from low-order to high-order; thus bit 0 is the lowest order
The op codes are as follows:
- Bits 0-3: Op code.
- Bits 4-7: First register argument
- Bits 8-25: Depending on the op code, either an address or a sequence
of additional register arguments, in 4 bit chunks from low-order to high-order.
- Bits 26-31: Unused.
| Op code || Abbreviation || Args || Meaning
| 0 || LOA || RA, AD || Load the value at AD into RA
| 1 || STO || RA, AD || Store the value at RA into AD
| 2 || CPR || RA, RB || Copy RB into RA
| 3 || LOI || RA, RB || RB holds the address of AD. Load the
value of AD into RA.
| 4 || STI || RA, RB || RA holds the address of AD. Store the
value in RB into AD.
| 5 || ADD || RA, RB, RC || RC = RA + RB
| 6 || SUB || RA, RB, RC || RC = RA - RB
| 7 || MUL || RA, RB, RC || RC = RA * RB
| 8 || DIV || RA, RB, RC, RD || RC = RA / RB; RD = RA % RB.
| 9 || ICR || RA || RA++
| 10 || DCR || RA || RA--
| 11 || GTR || RA, RB, RC || RC = (RA > RB)
| 12 || JMP || RA, AD || Jump to AD. (RA is unused).
| 13 || IFZ || RA, AD || If (RA == 0) then goto AD.
| 14 || JMI || RA || RA holds the address of AD. Jump to AD.
| 15 || TRP || || Trap to the kernel.
Note: The arithmetic operations are all integer. An instruction that has
two or more identical register arguments may have unexpected results.
Thus, for example, the hexadecimal value 0x11B0 consists of the opcode
0, the register value 0xB == 11, and the address 0x11 = 17, so
it indicates the instruction to load address 17 to register R11.
A user process executes a system call by executing an instruction of
the form "TRP". The value of register R15 indicates the nature of the system
call, as follows:
- R15 == 0. Terminate. The process halts.
R15 == 1. Input. Read an integer from standard input.
The value of the integer read is
returned to the process in register R14. R13 is returned as 1 if an integer
has been read and 0 if the end-of-file is reached. Any non-integer value
in standard input causes an error.
- R15 == 2. Output. Print on a new line to standard output in decimal
the value of the integer held in register R14.
- Project 2 will involve defining other trap codes, for forking
and for manipulating semaphores.
STML source files
A code file in STML has the following form:
You may assume that the STML file is correctly formatted.
- Line 1: Name of the process.
- Line 2: Size of the memory needed (including code, data, and variable
- Lines 3 onward: 1 instruction or data item per line, expressed as
an integer starting at the beginning of the line. Any line that does
not start with a digit is ignored.
Anything following the first integer on the line is ignored, and
may be used for comments.
Basic STM interpreter
A basic STM interpreter for a single process is available in
The program is executed with the following command line:
stm* [-b BASE] [-d DEBUGGING-LEVEL] [-m MAX] sml-file
The "-b", "-d", and "-m" flags may be given in any order; the file name
must be the last argument on the line.
- The optional argument "-b BASE" may be used with an integer value
for BASE to indicate where in memory the process partition should start.
Default value = 0.
- The optional argument "-d DEBUG" sets the level of debugging output:
Default value = 0.
- If DEBUG == 0, then the only output is that required by the STML code.
- If DEBUG == 1, then each time a TRP instruction is executed, the
program prints out the name of the process, the address of the instruction,
and the value of the R15 register.
- If DEBUG == 2, then each time any other instruction is executed,
the program prints out the name of the process, the address, op-code,
and arguments of the instruction.
- "sml-file" is the file containing the sml code.
The execution of the STM follows the standard "fetch-execute" cycle:
Execution continues until either the process intentionally terminates,
or aborts due to an error, or reaches the specified maximum number of
- 1. The instruction at the address contained in the PC is retrieved.
(The PC holds the relative address.)
- 2. The PC is incremented.
- 3. The instruction is executed.
Address translation: The addresses in STML are all relative
addresses. The base register holds the starting address of the process,
and the physical address is equal to the relative address plus the
base register. The limit register holds the size of the partition.
Any relative address that is less than 0 or greater than or equal to
the value of the limit register causes an error.
Errors: Any runtime error causes termination of the process.
I think that the following list includes all possible runtime errors:
All these errors except overflow are caught by the STM interpreter,
which exits smoothly. I am doubtful that there is any easy way to catch
overflow errors that will work on all systems. Therefore, these
are not intercepted, and will cause the STM interpreter to abort.
- Arithmetic errors: Overflow and divide by 0.
- Address errors: Relative address is not within bounds.
- PC increment error: Incrementing the PC causes its value to
fall outside the partition.
- Reading error: A non-integer is encountered in reading the input; or
an attempt to read past end-of-file.