Skip to the content of the web site.

ECE 150

IEEE Spectrum Magazine    MIT Technology Review    Wired Magazine    EDN Network    EE Times    Skeptic's Guide to the Universe

In this course, there will be opportunities for advanced students to gain greater understanding of the functioning of a computer while not overloading the schedules of those students who are new to programming.

One of those opportunities is understanding the machine instructions to which the programs written in C++ are converted to. Machine instructions are all binary numbers, and thus to make them human readable, we will introduce an intermediate assembly language where each assembly instruction corresponds to a machine instruction, only in human-readable form.

Assembly language must be necessarily precise, as you must be able to specify if you are performing operations on one, two, four or eight bytes, for example, and there are many instructions covering specific commands the purpose of which is not clear in first year, and they tend to be reasonably terse:

For example, an interesting site that shows MIPS assembly language examples is provided by an excellent web site at the Paul G. Allen School of Computer Science and Engineering at the University of Washington:

Given this for-loop,

	for ( size_t i = 0; i < capacity; i++ ) {
		A[i] = MAX_SIZE;
	}

an unoptimized for loop in assembly language is:

    add    $t0, $gp, $zero      # &A[0] - 28
    lw     $t1, 4($gp)          # fetch N
    sll    $t1, $t1, 2          # N as byte offset
    add    $t1, $t1, $gp        # &A[N] - 28
    ori    $t2, $zero, 256      # MAX_SIZE
top:
    sltu   $t3, $t0, $t1        # have we reached the final address?
    beq    $t3, $zero, done     # yes, we're done
    sw     $t2, 28($t0)         # A[i] = 0
    addi   $t0, $t0, 4          # update $t0 to point to next element
    j      top                  # go to top of loop
done:

We will try to make this more human-readable, although by third year, you should be very familiar with the above code:

Arithmetic operations

InstructionDescription
ADD Di + Dj -> Dk Add data registers 'i' and 'j' and put the output into data register 'k'
ADD Di + 'n' -> Dk Add the value 'n' to data register i and put the output into data register 'k'
SUBTRACT Di - Dj -> Dk Subtract data register 'j' from 'i' and put the output into data register 'k'
MULTIPLY Di * Dj -> Dk Multiply data registers 'i' and 'j' and put the output into data register 'k'
MULTIPLY Di * 'n' -> Dk Multiply the value 'n' by data register i and put the output into data register 'k'
DIVIDE Di / Dj -> Dk Divide data register 'i' by 'j' and put the output into data register 'k'

Branching operations

Like C++, you have to have some form of flow control; however, in assembly language, the natural flow control is essentially a goto statement: go to the instruction with a specified label:

InstructionDescription
BRANCH Di == Dj goto LABEL If data registers i and j are equal, branch to the label 'LABEL'
BRANCH Di == 'n' goto LABEL If data register i and 'n' are equal, branch to the label 'LABEL'
BRANCH Di != Dj goto LABEL If data registers i and j are not equal, branch to the label 'LABEL'
BRANCH Di != 'n' goto LABEL If data register i and 'n' are not equal, branch to the label 'LABEL'
BRANCH Di < Dj goto LABEL If data register i is less than data register j, branch to the label 'LABEL'
BRANCH Di < 'n' goto LABEL If data register i is less than 'n', branch to the label 'LABEL'
BRANCH Di <= Dj goto LABEL If data register i is not greater than data register j, branch to the label 'LABEL'
BRANCH Di <= 'n' goto LABEL If data register i is not greater than 'n', branch to the label 'LABEL'
BRANCH Di > Dj goto LABEL If data register i is greater than data register j, branch to the label 'LABEL'
BRANCH Di > 'n' goto LABEL If data register i is greater than 'n', branch to the label 'LABEL'
BRANCH Di >= Dj goto LABEL If data register i is not less than data register j, branch to the label 'LABEL'
BRANCH Di >= 'n' goto LABEL If data register i is not less than 'n', branch to the label 'LABEL'
BRANCH goto LABEL Branch unconditionally to the label 'LABEL'
RETURN-FROM-FUNCTION Branch unconditionally to the the point from which the function is called

Logical operations

All machine instructions related to logical operations are bit-wise, meaning the operation is applied to each of the bits.

InstructionDescription
AND Di & Dj -> Dk Take the bit-wise 'and' of registers 'i' and 'j' and put the output into data register 'k'
AND Di & 'n' -> Dk Take the bit-wise 'and' of register 'i' and the value 'n' and put the output into data register 'k'
OR Di | Dj -> Dk Take the bit-wise 'or' of registers 'i' and 'j' and put the output into data register 'k'
OR Di | 'n' -> Dk Take the bit-wise 'or' of register 'i' and the value 'n' and put the output into data register 'k'
XOR Di ^ Dj -> Dk Take the bit-wise 'xor' of registers 'i' and 'j' and put the output into data register 'k'
XOR Di ^ 'n' -> Dk Take the bit-wise 'xor' of register 'i' and the value 'n' and put the output into data register 'k'
NOT ~Di -> Dk Take the bit-wise 'not' of register 'i' and put the output into data register 'k'

The logical operations of &&, || and ! can be achieved by restricting the values stored in the data registers to either 0 or 1.

Memory operations

Address registers store the addresses of data or addresses stored in main memory. All data or addresses must be loaded into registers first before they are operated on.

InstructionDescription
LOAD (Ai) -> Dk Load the value at address in address register 'i' and save it to data register 'k'
LOAD (Ai + Dj) -> Dk Load the value at address in address register 'i' offset by data register 'j' and save it to data register 'k'
STORE Di -> (Aj) Store the value in data register 'i' to the address in address register 'j'
STORE Di -> (Aj + dk) Store the value in data register 'i' to address in address register 'j' offset by data register 'k'
WRITE 'n' -> Dj Store the value 'n' in data register 'j'

MIPS instruction set

In your second-year courses, you will start to look at various instruction sets. For example, Intel processors will use a different set of instructions than ARM processors which will differ again from instruction sets for Motorola processors, and different processor families within these companies will have different, but still recognizably similar, instruction sets. All of these instruction sets are proprietary, so one common non-proprietary instruction set is MIPS. This is the instruction set we are using as a basis for our easier instruction set above.

You can view the actual MIPS instruction set at this clean website from the University of Idaho.