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
#  程序结束
.macro end
li $v0, 10
syscall
.end_macro

#--------------------------

# 输入Integer
.macro readInt(%d)
li $v0, 5
syscall
move %d, $v0
.end_macro

#--------------------------

# 输出Interger
.macro printInt(%d)
li $v0, 1
move $a0, %d
syscall
.end_macro

#--------------------------

# 输出字符串(包括换行和空格)
# 值得一提的是,最好只使用".asciiz",因为它会字符串结尾添加一个结束符'\0'
.data
StrName: .asciiz "……"
# space: .asciiz " "
# enter: .asciiz "\n"
.macro printStr()
li $v0, 4
la $a0, StrName # 将输出字符串的地址赋给$a0
.end_macro

#--------------------------

# 保护和读取寄存器
# 临时寄存器不够用 或 递归函数使用
.macro push(%d)
sw %d, 0($sp)
addi $sp, $sp, -4
.end_macro

.macro pop(%d)
addi $sp, $sp, 4
lw %d, 0($sp)
.end_macro

#--------------------------

# 取二维数组下标地址
.macro getIndex(%d, %m, %i, %j) # m为列
mul %d, %m, %i
add %d, %d, %j
sll %d, %d, 2
.end_macro

一些tips

  • 取用指令时,记得多查看指令集手册和MARS的帮助手册(快捷键F1)。

虽然MARS没有代码补全功能,但是书写指令的时候会有提示(格式和大概用法等等)
所以指令记个大概也没关系,比如利用b->branch,g(t)->greater (than), z->zero等等可以很方便地写出多种多样的控制语句

  • 善用扩展指令 li,la,move
  • 灵活使用标签(并不一定要用来跳转)和缩进(,这样看起来能有一些层次感
  • 函数的调用和递归函数
    • jaljr配套
    • 传参一般使用$a0-$a3,返回值$v0-$v1
    • 关于写递归函数的时候什么东西要入栈,什么不要,其实很简单,只需要把进行递归前后发生变化的、且寄存器中的值关系到后续(递归回来)使用的寄存器进行保存和恢复就好了
    • 接上一条,进入函数的时候就先把要保存的进行入栈(包括$ra),然后在函数结束和return的地方进行出栈即可
  • 写一些必要的注释,标明寄存器保存的重要的变量和参数
  • 可以将对应的C程序写出,再对着翻译

课下提交

Q1 P2_L0_matrix

使用MIPS汇编语言编写一个具有矩阵相乘功能的汇编程序(不考虑延迟槽)。
具体要求:

  • 首先读取方形矩阵的阶数n,然后再依次读取第一个矩阵(n行n列)和第二个矩阵(n行n列)中的元素。
  • 两个矩阵的阶数相同,我们提供的测试数据中0<n≤8,每个矩阵元素是小于10的整数。
  • 最终将计算出的结果输出,每行n个数据,每个数据间用空格分开。评测机会自动过滤掉行尾空格以及最后的回车。
  • 使用syscall结束程序。

考察二维数组的使用

Code(仅供参考)
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
.data
arr1: .space 256
arr2: .space 256
arr3: .space 256
space: .asciiz " "
enter: .asciiz "\n"

.macro end
li $v0, 10
syscall
.end_macro

.macro readInt(%d)
li $v0, 5
syscall
move %d, $v0
.end_macro

.macro getIndex(%n, %d, %i, %j)
mul %d, %i, %n
add %d, %d, %j
sll %d, %d, 2
.end_macro

.macro printInt(%d)
li $v0, 1
move $a0, %d
syscall
.end_macro

.macro printEnter()
li $v0, 4
la $a0, enter
syscall
.end_macro

.macro printSpace()
li $v0, 4
la $a0, space
syscall
.end_macro

.text
main:
readInt($s0)
li $t0, 0
loop_i_1:
beq $t0, $s0, end_loop_i_1
li $t1, 0
loop_j_1:
beq $t1, $s0, end_loop_j_1
getIndex($s0, $t2, $t0, $t1)
li $v0, 5
syscall
sw $v0, arr1($t2)
addi $t1, $t1, 1
j loop_j_1
end_loop_j_1:
addi $t0, $t0, 1
j loop_i_1
end_loop_i_1:
li $t0, 0
loop_i_2:
beq $t0, $s0, end_loop_i_2
li $t1, 0
loop_j_2:
beq $t1, $s0, end_loop_j_2
getIndex($s0, $t2, $t0, $t1)
li $v0, 5
syscall
sw $v0, arr2($t2)
addi $t1, $t1, 1
j loop_j_2
end_loop_j_2:
addi $t0, $t0, 1
j loop_i_2
end_loop_i_2:

li $t0, 0
loop_i_3:
beq $t0, $s0, end_loop_i_3
li $t1, 0
loop_j_3:
beq $t1, $s0, end_loop_j_3
getIndex($s0, $t5, $t0, $t1)
lw $t5, arr3($t5)
li $t2, 0
loop_k_1:
beq $t2, $s0, end_loop_k_1
getIndex($s0, $t3, $t0, $t2)
getIndex($s0, $t4, $t2, $t1)
lw $t3, arr1($t3)
lw $t4, arr2($t4)
mult $t3, $t4
mflo $t3
add $t5, $t5, $t3
addi $t2, $t2, 1
j loop_k_1
end_loop_k_1:
getIndex($s0, $t3, $t0, $t1)
sw $t5, arr3($t3)
addi $t1, $t1, 1
j loop_j_3
end_loop_j_3:
addi $t0, $t0, 1
j loop_i_3
end_loop_i_3:

li $t0, 0
loop_i_4:
beq $t0, $s0, end_loop_i_4
li $t1, 0
loop_j_4:
beq $t1, $s0, end_loop_j_4
getIndex($s0, $t2, $t0, $t1)
lw $t2, arr3($t2)
printInt($t2)
printSpace()
addi $t1, $t1, 1
j loop_j_4
end_loop_j_4:
printEnter()
addi $t0, $t0, 1
j loop_i_4
end_loop_i_4:
end

Q2 P2_L0_judge

实现满足下面功能的汇编程序:

  1. 判断输入的字符串是不是回文串。
  2. 输出一个字符,是回文串输出1,否则输出0
  3. 每组数据最多执行100,000条指令。
  4. 使用syscall结束程序

注意如果一次读取一个字符($v0 = 12),记得使用lb,sb进行存取使用

Code(仅供参考)
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
.data
array: .space 20

.macro end
li $v0, 10
syscall
.end_macro

.macro readInt(%d)
li $v0, 5
syscall
move %d, $v0
.end_macro

.macro readCh(%d)
li $v0, 12
syscall
move %d, $v0
.end_macro

.text
readInt($s0)
li $t0, 0

loop1:
beq $t0, $s0, end_loop1
readCh($t1)
sb $t1, array($t0)
addi $t0, $t0, 1
j loop1

end_loop1:
li $t0, 0
addi $t2, $s0, -1
loop2:
beq $t0, $s0, end_loop2
lb $t1, array($t0)
sub $t3, $t2, $t0
lb $t3, array($t3)
bne $t1, $t3, not_equal
addi $t0, $t0, 1
j loop2

end_loop2:
li $a0, 1
li $v0, 1
syscall
end

not_equal:
li $a0, 0
li $v0, 1
syscall
end

Q3 P2_L0_conv

使用MIPS汇编语言编写一个进行卷积运算的汇编程序(不考虑延迟槽)。
具体要求:

  • 首先读取待卷积矩阵的行数m1和列数n1,然后读取卷积核的行数m2和列数n2。
  • 然后再依次读取待卷积矩阵(m1行n1列)和卷积核(m2行n2列)中的元素。
  • 输出中,有m1-m2+1行,每行有n1-n2+1个数据,每个数据用空格分开。
  • 卷积运算的定义:$$g(i, j) = \sum\limits_{k,l} f(i + k, j + l) \cdot h(k, l)$$其中f为待卷积矩阵,h为卷积核,g即为输出矩阵,k与l的终值分别为卷积核h的行大小、列大小。计算中不考虑边缘效应。
  • 使用syscall结束程序

Code(仅供参考)
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
129
130
131
132
133
134
135
136
137
138
139
140
.data
arrf: .space 400
arrh: .space 400
arrg: .space 400
space: .asciiz " "
enter: .asciiz "\n"

.macro end
li $v0, 10
syscall
.end_macro

.macro readInt(%d)
li $v0, 5
syscall
move %d, $v0
.end_macro

.macro printInt(%d)
li $v0, 1
move $a0, %d
syscall
.end_macro

.macro printEnter()
li $v0, 4
la $a0, enter
syscall
.end_macro

.macro printSpace()
li $v0, 4
la $a0, space
syscall
.end_macro

.macro getIndex(%d, %n, %i, %j)
mul %d, %n, %i
add %d, %d, %j
sll %d, %d, 2
.end_macro

.text
main:
readInt($s0)
readInt($s1)
readInt($s2)
readInt($s3)
li $t0, 0
loop_i_1:
beq $t0, $s0, end_loop_i_1
li $t1, 0
loop_j_1:
beq $t1, $s1, end_loop_j_1
getIndex($t2, $s1, $t0, $t1)
readInt($t3)
sw $t3, arrf($t2)
addi $t1, $t1, 1
j loop_j_1
end_loop_j_1:
addi $t0, $t0, 1
j loop_i_1
end_loop_i_1:
li $t0, 0
loop_i_2:
beq $t0, $s2, end_loop_i_2
li $t1, 0
loop_j_2:
beq $t1, $s3, end_loop_j_2
getIndex($t2, $s3, $t0, $t1)
readInt($t3)
sw $t3, arrh($t2)
addi $t1, $t1, 1
j loop_j_2
end_loop_j_2:
addi $t0, $t0, 1
j loop_i_2
end_loop_i_2:
move $s6, $s1
sub $s0, $s0, $s2
sub $s1, $s1, $s3
addi $s0, $s0, 1
addi $s1, $s1, 1
li $t0, 0

loop_i_3:
beq $t0, $s0, end_loop_i_3
li $t1, 0
loop_j_3:
beq $t1, $s1, end_loop_j_3
li $t2, 0
getIndex($s4, $s1, $t0, $t1)
lw $s5, arrg($s4)
loop_k_1:
beq $t2, $s2, end_loop_k_1
li $t3, 0
loop_l_1:
beq $t3, $s3, end_loop_l_1
add $t4, $t0, $t2
add $t5, $t1, $t3
getIndex($t6, $s6, $t4, $t5)
lw $t6, arrf($t6)
getIndex($t7, $s3, $t2, $t3)
lw $t7, arrh($t7)
mult $t6, $t7
mflo $t6
add $s5, $s5, $t6
addi $t3, $t3, 1
j loop_l_1
end_loop_l_1:
addi $t2, $t2, 1
j loop_k_1
end_loop_k_1:
sw $s5, arrg($s4)
addi $t1, $t1, 1
j loop_j_3
end_loop_j_3:
addi $t0, $t0, 1
j loop_i_3
end_loop_i_3:
li $t0, 0
loop_i_4:
beq $t0, $s0, end_loop_i_4
li $t1, 0
loop_j_4:
beq $t1, $s1, end_loop_j_4
getIndex($t2, $s1, $t0, $t1)
lw $t2, arrg($t2)
printInt($t2)
printSpace()
addi $t1, $t1, 1
j loop_j_4
end_loop_j_4:
printEnter()
addi $t0, $t0, 1
j loop_i_4
end_loop_i_4:
end


Q4 P2_L0_full_1

实现满足下面功能的汇编程序:

  1. 使用mips实现全排列生成算法。
  2. 以0x00000000为数据段起始地址。
  3. 输入一个小于等于6的正整数,求出n的全排列,并按照字典序输出。
  4. 每组数据最多执行500,000条指令。
  5. 使用syscall结束程序

C代码提示


一道递归题,注意递归返回的时候 即代码 FullArray(index+1); 后,除了保存恢复下标i,还要记得重新计算下标地址 需要用来撤销symbol标记( <<2 )

Code(仅供参考)
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
.data
array: .space 28
symbol: .space 28
space: .asciiz " "
enter: .asciiz "\n"

.macro end
li $v0, 10
syscall
.end_macro

.macro readInt(%d)
li $v0, 5
syscall
move %d, $v0
.end_macro

.macro printInt(%d)
li $v0, 1
move $a0, %d
syscall
.end_macro

.macro printEnter()
la $a0, enter
li $v0, 4
syscall
.end_macro

.macro printSpace()
la $a0, space
li $v0, 4
syscall
.end_macro

.macro push(%d)
sw %d, 0($sp)
addi $sp, $sp, -4
.end_macro

.macro pop(%d)
addi $sp, $sp, 4
lw %d, 0($sp)
.end_macro

.text
main:
readInt($s0)
li $t0, 0
li $t1, 0
li $a0, 0 # index
jal FullArray
end


FullArray:
push($ra)
push($t0)
push($t1)

move $t0, $a0 # index
li $t1, 0 # i
blt $t0, $s0, else1
if1:
loop1:
beq $t1, $s0, end_loop1
sll $t2, $t1, 2
lw $t2, array($t2) # array[i]
printInt($t2)
printSpace()
addi $t1, $t1, 1
j loop1
end_loop1:
printEnter()
pop($t1)
pop($t0)
pop($ra)
jr $ra # return
else1:
li $t1, 0
loop2:
beq $t1, $s0, end_loop2 # t1:i
sll $t2, $t1, 2
lw $t3, symbol($t2) # symbol[i]
bnez $t3, else2
if2:
sll $t3, $t0, 2 # index
addi $t4, $t1, 1
sw $t4, array($t3) # array[index] = i + 1
li $t3,1
sw $t3, symbol($t2) # symbol[i] = 1
addi $a0, $t0, 1 # new index
jal FullArray
li $t3, 0
sll $t2, $t1, 2 # remember to reset
sw $t3, symbol($t2) # symbol[i] = 0
else2:
addi $t1, $t1, 1
j loop2
end_loop2:
pop($t1)
pop($t0)
pop($ra)
jr $ra

附加题Q1 P2_L1_puzzle

使用深度优先探索算法求解01迷宫的逃离路线个数。
例
如左图,以红色0作为起点,绿色0作为终点,每一次行进只能选择上下左右中值为0且未走过的位置,满足上述条件的路线,即为一条迷宫逃跑路线。如右图中,蓝色的路线即为一条逃跑路线。

输入一个n*m的01矩阵作为01迷宫,并给定他的起点与终点,求出他不同逃跑路线的数目(不同逃跑路线中可以有相同的部分,但是不能完全相同)。


C代码
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
#include <stdio.h>
#include <stdlib.h>
int n,m,ans,target[4];
int Map[7][7];
int flag[7][7];
/*
s 0 1 0 0
1 0 0 0 1
1 0 1 0 1
1 0 0 0 t
*/
void dfs(int x, int y) {
//便于翻译就这么写了
if (x == target[2] && y == target[3]) {
++ans;
return;
}
if (x + 1 < n && Map[x + 1][y] == 0 && flag[x + 1][y] == 0) {
flag[x + 1][y] = 1;
dfs(x + 1, y);
flag[x + 1][y] = 0;
}
if (x > 0 && Map[x - 1][y] == 0 && flag[x - 1][y] == 0) {
flag[x - 1][y] = 1;
dfs(x - 1, y);
flag[x - 1][y] = 0;
}
if (y + 1 < m && Map[x][y + 1] == 0 && flag[x][y + 1] == 0) {
flag[x][y + 1] = 1;
dfs(x, y + 1);
flag[x][y + 1] = 0;
}
if (y > 0 && Map[x][y - 1] == 0 && flag[x][y - 1] == 0) {
flag[x][y - 1] = 1;
dfs(x, y - 1);
flag[x][y - 1] = 0;
}
}
int main() {
scanf("%d%d", &n, &m);
int i,j;
for(i = 0; i < n; ++i) {
for (j = 0; j < m; ++j) {
scanf("%d", &Map[i][j]);
}
}
for (i = 0; i < 4; ++i) {
scanf("%d", &target[i]);
target[i]--;
}
flag[target[0]][target[1]] = 1;
dfs(target[0],target[1]);
printf("%d\n", ans);
return 0;
}
Code(仅供参考)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
.data
Map: .space 196
flag: .space 196
space: .asciiz " "
enter: .asciiz "\n"

.macro end
li $v0, 10
syscall
.end_macro

.macro readInt(%d)
li $v0, 5
syscall
move %d, $v0
.end_macro

.macro printInt(%d)
li $v0, 1
move $a0, %d
syscall
.end_macro

.macro getIndex(%d, %m, %i, %j)
mul %d, %m, %i
add %d, %d, %j
sll %d, %d, 2
.end_macro

.macro push(%d)
sw %d, 0($sp)
addi $sp, $sp, -4
.end_macro

.macro pop(%d)
addi $sp, $sp, 4
lw %d, 0($sp)
.end_macro

.macro printSpace()
li $v0, 4
la $a0, space
syscall
.end_macro

.macro printEnter()
li $v0, 4
la $a0, enter
syscall
.end_macro

.macro check()
push($a0)
li $t6, 0
for_i:
beq $t6, $s0, end_for_i
li $t7, 0
for_j:
beq $t7, $s1, end_for_j
getIndex($t5, $s1, $t6, $t7)
lw $t5, flag($t5)
printInt($t5)
printSpace()
addi $t7, $t7, 1
j for_j
end_for_j:
printEnter()
addi $t6, $t6, 1
j for_i
end_for_i:
printEnter()
pop($a0)
.end_macro


.text
main:
readInt($s0)
readInt($s1)
li $s2, 0
li $t0, 0
loop_i_1:
beq $t0, $s0, end_loop_i_1
li $t1, 0
loop_j_1:
beq $t1, $s1, end_loop_j_1
getIndex($t2, $s1, $t0, $t1)
readInt($t3)
sw $t3, Map($t2)
addi $t1, $t1, 1
j loop_j_1
end_loop_j_1:
addi $t0, $t0, 1
j loop_i_1
end_loop_i_1:
readInt($t0)
readInt($t1)
readInt($s3)
readInt($s4)
addi $t0, $t0, -1
addi $t1, $t1, -1
addi $s3, $s3, -1 #target_x
addi $s4, $s4, -1 #target_y
getIndex($t2, $s1, $t0, $t1)
move $a0, $t0 # x
move $a1, $t1 # y
li $s5, 1 # const 1
sw $s5, flag($t2)
jal dfs
printInt($s2)
end

dfs:
push($ra)
push($t0)
push($t1)
move $t0, $a0
move $t1, $a1
bne $t0, $s3, else_1
bne $t1, $s4, else_1
if_1:
add $s2, $s2, 1
pop($t1)
pop($t0)
pop($ra)
jr $ra
else_1:
addi $t2, $t0, 1
beq $t2, $s0, else_2
getIndex($t3, $s1, $t2, $t1)
lw $t4, Map($t3)
bnez $t4, else_2
lw $t4, flag($t3)
bnez $t4, else_2
if_2:
sw $s5, flag($t3)
move $a0, $t2
move $a1, $t1
jal dfs
addi $t2, $t0, 1
getIndex($t3, $s1, $t2, $t1)
sw $0, flag($t3)
else_2:
beqz $t0, else_3
addi $t2, $t0, -1
getIndex($t3, $s1, $t2, $t1)
lw $t4, Map($t3)
bnez $t4, else_3
lw $t4, flag($t3)
bnez $t4, else_3
if_3:
sw $s5, flag($t3)
move $a0, $t2
move $a1, $t1
jal dfs
addi $t2, $t0, -1
getIndex($t3, $s1, $t2, $t1)
sw $0, flag($t3)
else_3:
addi $t2, $t1, 1
beq $t2, $s1, else_4
getIndex($t3, $s1, $t0, $t2)
lw $t4, Map($t3)
bnez $t4, else_4
lw $t4, flag($t3)
bnez $t4, else_4
if_4:
sw $s5, flag($t3)
move $a0, $t0
move $a1, $t2
jal dfs
addi $t2, $t1, 1
getIndex($t3, $s1, $t0, $t2)
sw $0, flag($t3)
else_4:
beqz $t1, else_5
addi $t2, $t1, -1
getIndex($t3, $s1, $t0, $t2)
lw $t4, Map($t3)
bnez $t4, else_5
lw $t4, flag($t3)
bnez $t4, else_5
if_5:
sw $s5, flag($t3)
move $a0, $t0
move $a1, $t2
jal dfs
addi $t2, $t1, -1
getIndex($t3, $s1, $t0, $t2)
sw $0, flag($t3)
else_5:
pop($t1)
pop($t0)
pop($ra)
jr $ra


附加题Q2 P2_L1_factorial

使用MIPS汇编语言编写一个求n的阶乘的汇编程序(不考虑延迟槽)。
具体要求:

  • 第一行读取n
  • 计算并输出n的阶乘,输出字符串长度小于等于1000
  • 步数限制为200,000
  • 使用syscall结束程序

C代码
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
#include <stdio.h>
#include <stdlib.h>
int n,len;
int a[1000];
int main()
{
scanf("%d", &n);
int i,j;
a[0] = 1, len = 1;
for (i = 2; i<=n; ++i) {
for (j = 0;j < len; ++j) {
a[j] *= i;
}
j = 0;
/*
对着翻译完才发现上面的for循环和while可以合成一个
但是懒得改了,数据也弱(
*/
while(a[j] || j < len) {
a[j + 1] += a[j] / 10;
a[j] %= 10;
++j;
}
len = j;
// printf("%d %d\n", i, len);
}
for (i = len - 1; i >= 0; --i) printf("%d", a[i]);
return 0;
}
Code(仅供参考)
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
.data
arr: .space 4000
space: .asciiz " "
enter: .asciiz "\n"

.macro end
li $v0, 10
syscall
.end_macro

.macro readInt(%d)
li $v0, 5
syscall
move %d, $v0
.end_macro

.macro printInt(%d)
li $v0, 1
move $a0, %d
syscall
.end_macro

.macro printEnter()
li $v0, 4
la $a0, enter
syscall
.end_macro

.macro printSpace()
li $v0, 4
la $a0, space
syscall
.end_macro

.text
main:
readInt($s0)
li $s1, 1 # len = 1
sw $s1, arr($0) # arr[0] = 1
li $t0, 2 # i
li $s2, 10 # const 10
loop_i_1:
bgt $t0, $s0, end_loop_i_1
li $t1, 0 # j
li $t2, 0 # index of arr[]
loop_j_1:
beq $t1, $s1, end_loop_j_1
lw $t3, arr($t2)
mul $t3, $t3, $t0
sw $t3, arr($t2)
addi $t2, $t2, 4
addi $t1, $t1, 1
j loop_j_1
end_loop_j_1:
li $t1, 0
li $t2, 0
while:
if_1:
lw $t3, arr($t2)
beqz $t3, if_2
j else
if_2:
bge $t1, $s1, end_while
else:
div $t3, $s2
mfhi $t3
sw $t3, arr($t2)
addi $t2, $t2, 4
lw $t3, arr($t2)
mflo $t4
add $t3, $t3, $t4
sw $t3, arr($t2)
addi $t1, $t1, 1
j while
end_while:
move $s1, $t1
addi $t0, $t0, 1
j loop_i_1
end_loop_i_1:
addi $t0, $s1, -1
sll $t0, $t0, 2
loop:
lw $t1, arr($t0)
printInt($t1)
beqz $t0, end_loop
addi $t0, $t0, -4
j loop
end_loop:
end

课上考试