MIPS R2000 Instructions, Program Structure

Tom Kelliher, CS26

Sept. 23, 1996

This will be our last look at the R2000 in class. We'll start in the classroom, then move into the lab.

R2000 Instructions

What follows are some key assembler directives and assembler instructions.

Assembler Directives

  1. .asciiz --- Store a null-terminated string in memory (in the .data segment).
    hello:      .asciiz "Hello world.\n"
    

  2. .data --- Declarator for starting a data segment.

  3. .globl --- Declarator for making a label externally visible. main must be made global and will be the starting point for program execution.
                .text
                .globl main
    main:       ...
    

  4. .space --- Allocate bytes in the data segment.
    array:      .space 20   # Allocates 20 bytes for array
    
    To allocate 20 words of memory use the following:
                .align 2
    array:      .space 80
    
    The .align is necessary to guarantee that the array is started on a word boundary.

  5. .text --- Declarator for starting a text (program code) segment.

  6. .word --- Allocate and initialize words of memory
    i:          .word 0
    array:      .word 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
    

System Calls

System calls are used for I/O and for returning control to the simulator.

All system calls require a system call code to be stored in register $v0 before making the call.

System calls which return values return them through register $v0.

  1. Print integer (system call code 1) --- The value to be printed must be stored in register $a0 before making the call.
                li $v0, 1
                li $a0, 13
                syscall
    

  2. Print string (system call code 4) --- The starting address of the string to be printed must be stored in register $a0 before making the call.
    hello:      .asciiz Hello world.\n"
                ...
                li $v0, 4
                la $a0, hello
                syscall
    
    Note the use of the load address instruction for loading the parameter.

  3. Read integer (system call code 5).
                li $v0, 5
                syscall
                sw $a0, n($0)
    

  4. Read string (system call code 8) --- The starting address of the array where the string will be stored must be stored in register $a0 and the size of the array (in bytes) must be stored in register $a1 before making the call.
    str:        .space 80
                ...
                li $v0, 8
                la $a0, str
                li $a1, 80
                syscall
    
    Again, note the use of load address.

  5. Exit and return to simulator (system call code 10).
                li $v0, 10
                syscall
    

Register Usage Conventions

As discussed, only registers $0 and $31 have usages defined by the architecture. What remains are software conventions.

I suggest that, in writing programs, you allocate registers starting with register $8 and ending with register $25.

(Taken from Larus' paper.)

Addressing Modes

Already discussed. Here are the names:

  1. Register.

  2. Immediate.

  3. Base.

  4. PC relative.

R2000 Assembler Instructions

This list is by no means exhaustive.

Any operand whose initial letter is R must be a register. Any operand whose initial letter is S may be a register or a 16-bit immediate value.

Arithmetic and Logical Instructions

add Rdest, Rsrc1, Src2 (with overflow)
Put the sum of the integers from register Rsrc1 and Src2 (or Imm) into register Rdest.

and Rdest, Rsrc1, Src2
Put the logical AND of the integers from register Rsrc1 and Src2 (or Imm) into register Rdest.

div Rsrc1, Rsrc2 (with overflow)
divu Rsrc1, Rsrc2 (without overflow)
Divide the contents of the two registers. Leave the quotient in register lo and the remainder in register hi. Note that if an operand is negative, the remainder is unspecified by the MIPS architecture and depends on the conventions of the machine on which SPIM is run.

mult Rsrc1, Rsrc2
multu Rsrc1, Rsrc2 Multiply
Multiply the contents of the two registers. Leave the low-order word of the product in register lo and the high-word in register hi.

not Rdest, Rsrc
Put the bitwise logical negation of the integer from register Rsrc into register Rdest.

or Rdest, Rsrc1, Src2
ori Rdest, Rsrc1, Imm Immediate
Put the logical OR of the integers from register Rsrc1 and Src2 (or Imm) into register Rdest.

rol Rdest, Rsrc1, Src2 Left
ror Rdest, Rsrc1, Src2 Right
Rotate the contents of register Rsrc1 left (right) by the distance indicated by Src2 and put the result in register Rdest.

sll Rdest, Rsrc1, Src2 Left Logical
sra Rdest, Rsrc1, Src2 Right Arithmetic
srl Rdest, Rsrc1, Src2 Right Logical
Shift the contents of register Rsrc1 left (right) by the distance indicated by Src2 ( Rsrc2) and put the result in register Rdest.

sub Rdest, Rsrc1, Src2 (with overflow)
Put the difference of the integers from register Rsrc1 and Src2 into register Rdest.

Constant-Manipulating Instructions

li Rdest, imm Immediate
Move the immediate imm into register Rdest.

lui Rdest, imm Upper Immediate
Load the lower halfword of the immediate imm into the upper halfword of register Rdest. The lower bits of the register are set to 0.

Branch and Jump Instructions

Branch instructions use a signed 16-bit offset field; hence they can jump instructions (not bytes) forward or instructions backwards. The jump instruction contains a 26 bit address field.

b label instruction
Unconditionally branch to the instruction at the label.

beq Rsrc1, Src2, label on Equal
Conditionally branch to the instruction at the label if the contents of register Rsrc1 equals Src2.

beqz Rsrc, label on Equal Zero
Conditionally branch to the instruction at the label if the contents of Rsrc equals 0.

bge Rsrc1, Src2, label on Greater Than Equal
bgeu Rsrc1, Src2, label on GTE Unsigned
Conditionally branch to the instruction at the label if the contents of register Rsrc1 are greater than or equal to Src2.

bgez Rsrc, label on Greater Than Equal Zero
Conditionally branch to the instruction at the label if the contents of Rsrc are greater than or equal to 0.

bgt Rsrc1, Src2, label on Greater Than
bgtu Rsrc1, Src2, label on Greater Than Unsigned
Conditionally branch to the instruction at the label if the contents of register Rsrc1 are greater than Src2.

bgtz Rsrc, label on Greater Than Zero
Conditionally branch to the instruction at the label if the contents of Rsrc are greater than 0.

ble Rsrc1, Src2, label on Less Than Equal
bleu Rsrc1, Src2, label on LTE Unsigned
Conditionally branch to the instruction at the label if the contents of register Rsrc1 are less than or equal to Src2.

blez Rsrc, label on Less Than Equal Zero
Conditionally branch to the instruction at the label if the contents of Rsrc are less than or equal to 0.

blt Rsrc1, Src2, label on Less Than
bltu Rsrc1, Src2, label on Less Than Unsigned
Conditionally branch to the instruction at the label if the contents of register Rsrc1 are less than Src2.

bltz Rsrc, label on Less Than Zero
Conditionally branch to the instruction at the label if the contents of Rsrc are less than 0.

bne Rsrc1, Src2, label on Not Equal
Conditionally branch to the instruction at the label if the contents of register Rsrc1 are not equal to Src2.

bnez Rsrc, label on Not Equal Zero
Conditionally branch to the instruction at the label if the contents of Rsrc are not equal to 0.

j label
Unconditionally jump to the instruction at the label.

jal label and Link
jalr Rsrc and Link Register
Unconditionally jump to the instruction at the label or whose address is in register Rsrc. Save the address of the next instruction in register 31.

jr Rsrc Register
Unconditionally jump to the instruction whose address is in register Rsrc.

Load Instructions

la Rdest, address Address
Load computed address, not the contents of the location, into register Rdest.

lb Rdest, address Byte
lbu Rdest, address Unsigned Byte
Load the byte at address into register Rdest. The byte is sign-extended by the lb, but not the lbu, instruction.

lw Rdest, address Word
Load the 32-bit quantity (word) at address into register Rdest.

Store Instructions

sb Rsrc, address Byte
Store the low byte from register Rsrc at address.

sw Rsrc, address Word
Store the word from register Rsrc at address.

Data Movement Instructions

move Rdest, Rsrc
Move the contents of Rsrc to Rdest.

The multiply and divide unit produces its result in two additional registers, hi and lo. These instructions move values to and from these registers. The multiply, divide, and remainder instructions described above are pseudoinstructions that make it appear as if this unit operates on the general registers and detect error conditions such as divide by zero or overflow.

mfhi Rdest From hi
mflo Rdest From lo
Move the contents of the hi (lo) register to register Rdest.

mthi Rdest To hi
mtlo Rdest To lo
Move the contents register Rdest to the hi (lo) register.

Exception and Trap Instructions

nop operation
Do nothing.

Program Structure

Write R2000 code fragments corresponding to the following:

  1. if (i < 12 && j > 3 || k != 0)
       ++i;
    else if (i == 33)
       --j;
    else
       k += 2;
    

  2. while (i > 0 && i < 200)
    {
       i = j;
       i *= i;
    }
    

  3. for (i = 1; i <= 32 ; i *= 2)
       cout << i << endl;
    

Ok, now we go down to the lab to contiue on the exercises.



Thomas P. Kelliher
Mon Sep 23 10:37:04 EDT 1996
Tom Kelliher