CSc 116 notes

Previous page Back    Next Next page  Contents

4) Basic assembly language instructions

In this course we will be dealing with instructions on 3 different, relatively low, levels. Starting from the lowest (found left to right in the SPIM text segment window) they are:
  1. binary machine instructions (shown in hexadecimal)
  2. symbolic actual machine instructions. Registers shown numerically ($31)
  3. assembly language (nicer) instructions, the ones you write in a source file, registers can be referred to symbolically ($ra)
The correspondance is usually 1:1, however, since RISC is a Reduced instruction set, some normal and useful assembly language instructions can be coded as one or two other, less intuitive, instructions, so the assembler provides a limited translation service. In this section, I will only describe the nice instructions at level 3.


Load and store instructions

These instructions are used to move data between memory and the processor. There are always 2 operands, a register and an address. Addresses can take several forms, as we shall see, the simplest is the label of a data item.

In this example, a word (32 bits) is moved from Num1 to Num2, and a copy is left in register $t0:

        lw    $t0, Num1    # load word,  $t0 := Num1
        sw    $t0, Num2    # store word, Num2 := $t0
Note the order of the operands, the register is always first. The direction of movement is opposite.

There are similar instructions to load and store bytes (8 bits), half-words (16 bits), and double-words (64 bits)

Load immediate (constant)

There are also 2 instructions that load a constant, which is incorporated into the instruction itself (immediate): Since a label represents a fixed memory address after assembly, la is actually a special case of load immediate.

Note the difference between lw and la: If Num1 is at location [0x10001000] and contains 0xfffffffe (-2), then


Arithmetic

Arithmetic is done in registers. There are 3 operands to an arithmetic operation:
  1. destination register
  2. Source 1 register
  3. Source 2 register or constant
The compact way of writing this pattern is:    add   Rdest, Rsrc1, Src2
The following code calculates the expression (x + 5 - y) * 35 / 3
           lw    $t0, x             #load x from memory
           lw    $t1, y             #load y from memory
           add   $t0, $t0, 5        # x + 5
           sub   $t0, $t0, $t1      # x + 5 - y  
           mul   $t0, $t0, 35       #(x + 5 - y)*35
           div   $t0, $t0, 3        #(x + 5 - y)*35/3

Arithmetic overflow, signed numbers

add, sub, mulo, & div check for overflow of signed numbers, an incorrect result, in which the sign bit is improperly altered. (mul doesn't do any checking). Usually we want to work with signed numbers. The processor generates an exception, "arithmetic overflow," and stops the program. This is preferable to generating incorrect results, as is usually the case with older processors, which generate a "flag" which programmers typically ignore.

Unsigned numbers

Sometimes we want to work with unsigned numbers. In this case overflow checking is unwanted. Generally we append a u to the operation code to express our intent. The unsigned operation codes are:
      addu,  subu,  mulou,   divu
This also applies to the short load instructions, lb and lh. They normally fill the unused part of the register with the sign bit of the short data. If we want to guarantee that the high part of the register is filled with 0's, we can use lbu & lhu instead. For example, we generally think of a character as an unsigned value.


Input and Output - System calls

Controlling the hardware responsible for input and output is a difficult and specialized job, and beyond the scope of this course. All computers have an operating system that provides many services for input/output anyway. The SPIM simulator provides 10 basic services. The ones we will be using right now are given here. The others are for floating point (real) numbers. The call code always goes in $v0, and the system is called with syscall.
Service Call code Arguments 
(input)
Results
print integer 1 $a0 = integer signed decimal integer
printed in console window
print string 4 $a0 = address 
         of string
string printed in console window
read integer 5 (none) $v0 holds integer 
that was entered
read string 8 $a0=address to store 
$a1= length limit
characters are stored
exit 10 (none) Ends the program
An example: A simple program to input and add 2 numbers

Prepared by Lin Jensen, Bishop's University, 20 January 1999

Previous page Back      Next Next page       Contents