Instructions are all 32 bits byte(8 bits), halfword (2 bytes), word (4 bytes) a character requires 1 byte of storage an integer requires 1 word (4 bytes) of storage
example: .data var1: .word 23 # declare storage for var1; initial value is 23 .text __start: lw $t0, var1 # load contents of RAM location into register $t0: $t0 = var1 li $t1, 5 # $t1 = 5 ("load immediate") sw $t1, var1 # store contents of register $t1 into RAM: var1 = $t1 done
load address
直接给地址
1
la $t0, var1
copy RAM address of var1 (presumably a label defined in the program) into register $t0
indirect addressing
1
lw $t2, ($t0)
load word at RAM address contained in $t0 into $t2
1
sw $t2, ($t0)
store word in register $t2 into RAM at address contained in $t0
based or indexed addressing
1
lw $t2, 4($t0)
• load word at RAM address ($t0+4) into register $t2 • “4” gives offset from address in register $t0
1
sw $t2, -12($t0)
• store word in register $t2 into RAM at address ($t0 - 12) • negative offsets are fine
Note: based addressing is especially useful for: • arrays; access elements as offset from base address • stacks; easy to access elements at offset from stack pointer or frame pointer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
.data array1:.space12 # declare 12 bytes of storage to hold array of 3 integers .text __start: la $t0, array1 li $t1, 5 sw $t1, ($t0) # first array element set to 5; indirect addressing li $t1, 13 sw $t1, 4($t0) # second array element set to 13 li $t1, -1 sw $t1, 8($t0) # third array element set to -7 done
算术指令集
最多3个操作数
操作数只能是寄存器,绝对不允许出现地址
所有指令统一是32位 = 4*8 bit = 4bytes = 1 word
add
1
add $t0,$t1,$t2
$t0 = $t1 + $t2 add as signed (2’s complement) integers
1
addi $t2,$t3, 5
$t2 = $t3 + 5 “add immediate” (no sub immediate)
1
addu $t1,$t6,$t7
$t1 = $t6 + $t7 add as unsigned integers
sub
1
sub $t2,$t3,$t4
$t2 = $t3 - $t4
1
subu $t1,$t6,$t7
$t1 = $t6 - $t7 subtract as unsigned integers
mult
1
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
1
div $t5,$t6
Lo = $t5 / $t6 (integer quotient) Hi = $t5 mod $t6 (remainder)
mfhi/mflo
1
mfhi $t0
move quantity in special register Hi to $t0: $t0 = Hi
1
mflo $t1
move quantity in special register Lo to $t1: $t1 = Lo
used to get at result of product or quotient
1
move $t2,$t3
$t2 = $t3
控制流
Branches
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
1 2
j target # unconditional jump to program label target
看到就跳, 不用考虑任何条件
1 2
jr $t3 # jump to address contained in $t3 ("jump register")
类似相对寻址,跳到该寄存器给出的地址处
Subroutine Calls
1 2
jal sub_label # "jump and link"
• copy program counter (return address) to register $ra (return address register) • jump to program statement at sub_label
1
jr $ra # "jump register"
• jump to return address in $ra (stored by jal instruction) Note : return address 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 hence will overwrite previous value 如果说调用的子程序中有调用了其他子程序,如此往复, 则返回地址的标记就用 栈(stack) 来存储, 毕竟 $ra 只有一个
System Calls and I/O
通过系统调用实现终端的输入输出,以及声明程序结束
学会使用 syscall
参数所使用的寄存器:$v0, $a0, $a1
返回值使用: $v0
Service
Code in $v0
Arguments
Results
print_int
$v0 = 1
$a0 = integer to be printed
print_float
$v0 = 2
$f12 = float to be printed
print_double
$v0 = 3
$f12 = double to be printed
print_string
$v0 = 4
$a0 = address of string in memory
read_int
$v0 = 5
integer returned in $v0
read_float
$v0 = 6
float returned in $v0
read_double
$v0 = 7
double returned in $v0
read_string
$v0 = 8
$a0 = memory address of string input buffer $a1 = length of string buffer (n)