CSAPP-MIPS

Registers 寄存器

1.一共有32个general register

2.有两种使用方法: 直接使用对应的编号或者是对应的寄存器名称

寄存器编号 寄存器名称 寄存器用途
0 zero return 0
1 $at 汇编保留寄存器
2-3 $v0-$v1 (value)存储表达式或者是函数的返回值
4-7 $a0-$a3 (Argument) 存储子程序前四个参数,调用时不保存
8-15 $t0-$t7 临时变量,调用时不保存,调用完成后要恢复
16-23 $s0-$s7 函数调用的时候必须保存,调用完成后需要恢复
24-25 $t8-$t9 属性和$t0-$t7一致
26-27 $k0-$k1 (kernel)中断函数返回值
28 $gp global pointer 指向64K大小的静态数据块的中间地址
29 $sp stack pointer
30 $fp/$s8 frame pointer
31 $ra return address

Program Structure 程序结构

本质其实就只是数据声明+普通文本+程序编码(文件后缀为.s,或者.asm也行) 数据声明在代码段之后(其实在其之前也没啥问题,也更符合高级程序设计的习惯)
Data Declarations 数据声明

数据段以 .data为开始标志
声明变量后,即在主存中分配空间。

Code 代码

代码段以 .text为开始标志
其实就是各项指令操作
程序入口为main:标志
程序结束标志(详见下文)
模板
1
2
3
4
5
		.data  # 数据变量声明

.text #代码段

main: 主函数入口

数据声明

example

var1:   .word 3

array:   .byte ‘a’,’b’ # 声明一个存储两个字符的数组array1,并赋值’a’,’b’

array1:   .space 40 #为变量array2 分配40个未使用的连续空间


其他指令汇总

MIPS入门

实战-冒泡排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128


.data
array: .space 1024
input_msg: .asciiz "Enter the number of integers:\n"
input_int_msg: .asciiz "Enter integers to be sorted\n"
output_msg: .asciiz "the sorted numbers are\n"


.text
.globl main

main:
la $a0,input_msg
li $v0,4
syscall

li $v0,5 #接受用户输入的数组长度
syscall



la $t6,array #数组首地址
move $t7,$zero #循环变量i
move $t8,$zero #循环变量j
move $t9,$v0 #数组长度

addi $t3,$zero,1
beq $v0,$t3,special

input:

la $a0,input_int_msg
li $v0,4
syscall


li $v0,5
syscall

#for(int i=0;i<num;i++)
#cin>>arr[i];

move $t0,$t7 #$t0 is i
sll $t0,$t0,2 #i become byte offset
move $t1,$t6 #$t1 is &array[0]
add $t1,$t1,$t0 #$t1 is &array[i]
sw $v0,0($t1) #cin>>array[i]

addi $t7,$t7,1
blt $t7,$t9,input #if ++i<length

move $t7,$zero

loop1: # 每次外层循环比内层循环的循环变量设为0
move $t8,$zero
loop2:
#read arr[j+1] and arr[j]

move $t2,$t8 #t2 is j
sll $t2,$t2,2 #j=*4;
addu $t1,$t2,$t6 #&arr[j]
lw $t4,0($t1) #arr[j]


addi $t2,$t8,1 #j+1
sll $t2,$t2,2 #(j+1)*4
addu $t0,$t2,$t6 #&arr[j+1]
lw $t5,0($t0) #$t5 = arr[j+1]


bge $t5,$t4,skip #if arr[j+1]>arr[j] skip

sw $t5,0($t1)
sw $t4,0($t0)

skip:


addi $t8,$t8,1 #j++
subi $t1,$t9,1 #t1 = num-1
sub $t1,$t1,$t7 #t1 = num-1-i
blt $t8,$t1,loop2 # if j<num-i-1 t2=1
addi $t7,$t7,1 #i++
sub $t3,$t9,1
blt $t7,$t3,loop1 #if i<num-1 then continue loop1
j output

special:
la $a0,input_int_msg
li $v0,4
syscall


li $v0,5
syscall

#for(int i=0;i<num;i++)
#cin>>arr[i];

move $t0,$t7 #$t0 is i
sll $t0,$t0,2 #i become byte offset
move $t1,$t6 #$t1 is &array[0]
add $t1,$t1,$t0 #$t1 is &array[i]
sw $v0,0($t1) #cin>>array[i]

output:

la $a0,output_msg
li $v0,4
syscall

move $t7,$zero
print:

move $t0,$t7

sll $t0,$t0,2

add $t1,$t6,$t0

lw $a0,0($t1) #argument a0

li $v0,1
syscall

addi $t7,$t7,1
blt $t7,$t9,print