changhengliou / ECE-6913

2 stars 1 forks source link

MIPS intro #1

Open changhengliou opened 4 years ago

changhengliou commented 4 years ago

Program structure

.data            # variable declarations follow this line
x:      .word    701     # create a single integer variable x with initial value 701
y:      .word    701     # create a single integer variable y with initial value 701

arr:    .byte    'a','b'   # create a 2-element character array with elements initialized as 'a' and 'b'

arr2:    .space 40  # allocate 40 consecutive bytes, with storage uninitialized
            #   could be used as a 40-element character array, or a
            #   10-element integer array; a comment should indicate which!

.text  # instructions follow this line  
main:  # program starting point
   lw $t0,x              # loads `$t0` with 701
   lw $t1,y              # loads `$t1` with 701
   bge $t0, $t1, end       #compares $t0 and $t1, if equal, jump to address [end]

end: 
  # the code segment for end label

Registers

Register Number Alternative Name Description
0 zero the value 0
1 $at (assembler temporary) reserved by the assembler
2-3 $v0-$v1 (values) from expression evaluation and function results
4-7 $a0-$a3 (arguments) First four parameters for subroutine.Not preserved across procedure calls
8-15 $t0-$t7 (temporaries) Caller saved if needed. Subroutines can use w/out saving.Not preserved across procedure calls
16-23 $s0-$s7 (saved values) - Callee saved.A subroutine using one of these must save original and restore it before exiting.Preserved across procedure calls
24-25 $t8-$t9 (temporaries) Caller saved if needed. Subroutines can use w/out saving.These are in addition to $t0 - $t7 above.Not preserved across procedure calls.
26-27 $k0-$k1 reserved for use by the interrupt/trap handler
28 $gp global pointer.Points to the middle of the 64K block of memory in the static data segment.
29 $sp stack pointerPoints to last location on the stack.
30 $s8/$fp saved value / frame pointerPreserved across procedure calls
31 $ra return address

Load / Store Instructions

RAM access only allowed with load and store instructions, other instructions use register operands

Load:

# copy word (4 bytes) at source RAM location to destination register.
lw register_destination, RAM_source 

copy byte at source RAM location to low-order byte of destination register

lb register_destination, RAM_source

###### Store:

store word in source register into RAM destination

sw register_source, RAM_destination

store byte (low-order) in source register into RAM destination

sb register_source, RAM_destination


###### Load immediate:

load immediate value into destination register

li register_destination, value


###### Load address:

copy RAM address of var1 into register $t0

la $t0, var1


###### Indirect addressing:

load word at RAM address contained in $t0 to $t2

lw $t2, ($t0)

store $t2 to RAM address contained in $t0

sw $t2, ($t0)


###### Indexed addressing:

load word at RAM address contained in $t0 + 4 to $t2

lw $t2, 4($t0)

load word at RAM address contained in $t0 - 12 to $t2

sw $t2, -12($t0)

    .data

array1: .space 12 # declare 12 bytes of storage to hold array of 3 integers .text __start: la $t0, array1 # load base address of array into register $t0 li $t1, 5 # $t1 = 5 ("load immediate") sw $t1, ($t0) # first array element set to 5; indirect addressing li $t1, 13 # $t1 = 13 sw $t1, 4($t0) # second array element set to 13 li $t1, -7 # $t1 = -7 sw $t1, 8($t0) # third array element set to -7 done


#### Arithmetic Instructions

add $t0,$t1,$t2 # $t0 = $t1 + $t2; add as signed (2's complement) integers sub $t2,$t3,$t4 # $t2 = $t3 - $t4 addi $t2,$t3, 5 # $t2 = $t3 + 5; add immediate addu $t1,$t6,$t7 # $t1 = $t6 + $t7; add as unsigned integers subu $t1,$t6,$t7 # $t1 = $t6 + $t7; subtract as unsigned integers

mult $t3,$t4 # multiply 32-bit quantities in $t3 and $t4, and store 64-bit

result in special registers Lo and Hi: (Hi,Lo) = $t3 * $t4

div $t5,$t6 # Lo = $t5 / $t6 (integer quotient)

Hi = $t5 mod $t6 (remainder)

mfhi $t0 # move quantity in special register Hi to $t0: $t0 = Hi mflo $t1 # move quantity in special register Lo to $t1: $t1 = Lo

used to get at result of product or quotient

move $t2,$t3 # $t2 = $t3


#### Control Structures
###### Controls

b target # unconditional branch to program label target beq $t0,$t1,target # branch to target if $t0 = $t1 blt $t0,$t1,target # branch to target if $t0 < $t1 ble $t0,$t1,target # branch to target if $t0 <= $t1 bgt $t0,$t1,target # branch to target if $t0 > $t1 bge $t0,$t1,target # branch to target if $t0 >= $t1 bne $t0,$t1,target # branch to target if $t0 <> $t1


###### Jumps

j target # unconditional jump to program label target jr $t3 # jump to address contained in $t3 (jump register)

copy program counter (return address) to register $ra (return address register)

jump to program statement at sub_label

jal sub_label # jump and link

jr $ra # jump register, jump to return address $ra


Return address is stored in register `$ra`; **if subroutine will call other subroutines, or is recursive, return address should be copied from `$ra` onto stack to preserve it, since `jal` always places return address in this register and will overwrite previous value**
changhengliou commented 4 years ago

Arguments

Arguments are stored by registers $a0 - $a3

void takesArguments(int x, int y) {
  x = x + y;
}

takesArguments(3, 4);

# above becomes below

li    $a0 3
li    $a1 4
jal   takesArgument

takesArguments:
  add    $a0, $a0, $a1
  jr     $ra
changhengliou commented 4 years ago

Return value

Return value are stored by registers $v0 and $v1


int addTwo(int x, int y) {
return x + y;
}

above becomes below

addTwo: add $v0, $a0, $a1 jr $ra

changhengliou commented 4 years ago

Temp value

Temp value is used by registers $t0 - $t7

int needsTemps(int x, int y) {
  int add = x + y;
  int sub = x - y;
  int mult = add * sub;
  return mult;
}

# above becomes below

needsTemps:
  add $t0, $a0, $a1
  sub $t1, $a0, $a1
  mult $t0, $t1
  mflo $t2
  move $v0, $t2
  jr $ra
changhengliou commented 4 years ago

Push/Pop stack

push $ra

addiu $sp, $sp, -4
sw $ra, 0($sp)
void fourth() {}
void third() {
  fourth();
}
void second() {
  third();
}
void first() {
  second();
  exit();
}

# above becomes below

fourth:
  jr $ra

third:
  addiu $sp, $sp, -4
  sw $ra, 0($sp)
  jal fourth
  lw $ra, 0($sp)
  addiu $sp, $sp, 4
  jr $ra

second:
  addiu $sp, $sp, -4
  sw $ra, 0($sp)
  jal third
  lw $ra, 0($sp)
  addiu $sp, $sp, 4
  jr $ra

first:
  jal second

  # perform the exit syscall from SPIM
  li $v0, 10
  syscall