skip navigational linksPJRC
Shopping Cart Checkout Shipping Cost Download Website
Home MP3 Player 8051 Tools All Projects PJRC Store Site Map
You are here: OSU8 Microprocessor CPU Programming Instruction Set Search PJRC

OSU8 Microprocessor
CPU Programming
Hardware Info
Download Files

Instruction Set, Design Objectives

The two primary goals in defining the instruction set were to provide enough functionality to write real programs, and to keep the opcode format simple. Other common goals, such as fast execution of common algorithms, minimal usage of code memory, and support for compilers were not considered important.

The opcode format was kept simple, with the expectation that a complex opcode format would make the project more difficult. All instructions are encoded as a single 8-bit byte. This was done in the hope that it would simplify the design of the control circuitry, before I wound up creating the microcode programming language.

CPU Architecture Decisions

After reviewing the architectures of many chips, including the Intel 8047, 8051, 8086, Motorola 6502, 68000, and a couple others, and the limitations of using only 8 bits for all opcodes, many decisions were made, which ultimately lead to the final instruction set definition.

A 16-bit address space was chosen, and of course the data path would be 8-bits wide. A standard von Neumann memory model was chosen, as it seemed simpler and would reduce the number of pins required.

Addressing Modes

Direct addressing was the first sacrifice. Indirect and immediate (constant load) addressing are both required, and they can be used together to achieve "direct" access to memory. Load and store, push, pop, relative program branching also were considered absolutely necessary.


Two data registers, two address pointer registers, and one stack pointer were chosen as the minimum "reasonable" set of registers. Four status bits, Carry, Negative, Zero, and Pointers Equal were chosen. These are the only registers visible to the programmer.

Immediate Addressing

There must be instructions that can load the registers with constants. Since it was decided at the beginning to use 8-bit opcode for all instructions, 4 bits were alloced to be data for these load instructions. 32 of the 256 opcode would be needed to be able to load just on 8 bit register. Ultimately I allocated half of all the 256 opcodes, to allow both of the data registers and one of the 16 bit pointers to be loaded with immediate data, without needing to move data between other registers.

Register to Register Math Functions

Because 4 bits had been allocated for constant data, it seemed a wise choice to define 16 math functions involving the data registers. At least for a great number of the instructions, 4 bits would indicate the overall function, and the remaining four would be treated as data or input to the ALU's control lines.

Program Branching

One of the most difficult decisions in the instruction set was how to handle program branching. Without many bits to use, it seemed impossible... at least at first. Unconditional branching and subroutine calls would be handled by using the first 16 bit memory pointer. Conditional branching was handled by requiring the target of a branch to be aligned on a 32 bit boundry. This would allow a branch, using 4 bits to specify the target of the branch, to jump up to 68 bytes away. The downside is that NOP instructions must be added before any instruction that will be the target of such a branch, but the assembler can be written to take care of this automatically. By requiring the branch target to be on an 32-bit boundry, and not a multiple of 4 bytes away from the branch instruction, the padded NOP instructions would not end up inside of a loop, where a branch at the bottom of the loop would branch back to the top. Two blocks of 16 opcodes were allocated, to allow a wide branching range.

Moving Data Around

It seems like most assembly language code is composed mostly of move instructions. Move instructions, push, pop, and bit move instructions to transfer bits to and from the carry bit (the only bit for condiction branch) were added.

Instruction Set

The original instruction set document is still the only complete specification of the instruction set.

(someday I may add a more easy-to-read instruction set summary here)

OSU8: Simple 8-Bit Microprocessor Design; Paul Stoffregen
Last updated: February 24, 2005
Status: These pages are a work-in-progress
Comments, Suggestions: <>