BUAA_CO_P2
P2
汇编语言
目录:
[toc]
宏定义
P2_L0_Matrix
和P2_L1_factorial
涉及矩阵读入,运算与输出。可以使用一些宏定义可以增加代码可读性: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.data
str_enter : .asciiz "\n" # .asciiz 伪指令用于定义一个以空字符结尾的字符串常量。
str_space : .asciiz " " # .ascii 伪指令不包含结尾处的空字符
.macro printSpace # 输出一个空格
la $a0, str_space # 用于将标签或变量的地址加载到指定的寄存器中。
li $v0, 4
syscall
.end_macro
.macro printEnter # 输出一个换行符
la $a0, str_enter
li $v0, 4
syscall
.end_macro
.macro getInt(%des) # 读入一个整数到指定的寄存器
li $v0, 5
syscall
move %des, $v0
.end_macro
.macro printInt(%des) # 打印一个整数
move $a0, %des
li $v0, 1
syscall
.end_macro
.macro end # 结束程序
li $v0, 10
syscall
.end_macro由于矩阵是储存在内存堆中的,矩阵运算需要频繁的涉及访存操作,用宏定义简化该过程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20.data
matrix : .space 256 # 申请256字节连续空间用以储存矩阵
#### 使用宏定义简化访存操作
.macro save(%desn, %dest, %desi, %desj) # 把寄存器%dest的值存入matrix[i][j]
mult %desn, %desi # Lo = n * i
mflo $t3 # t3 = n * i
add $t3, $t3, %desj # t3 = n * i + j
sll $t3, $t3, 2 # offset = t3 = t3 << 2
sw %dest, matrix($t3) # matrix[i][j] = t0
.end_macro
.macro get(%desn, %des, %desi, %desj) # 把matrix[i][j]的值存入寄存器%dest
mult %desn, %desi # Lo = n * i
mflo $t3 # t3 = n * i
add $t3, $t3, %desj # t3 = n * i + j
sll $t3, $t3, 2 # offset = t3 = t3 << 2
lw %des, matrix($t3) # matrix[i][j] = t0
.end_macroP2_L0_full
和P2_L1_puzzle
涉及到递归操作,这需要频繁的入栈和出栈操作。我们同样通过宏定义的方式来简化该过程:1
2
3
4
5
6
7
8
9.macro push(%src) # 入栈
addi $sp, $sp, -4
sw %src, 0($sp)
.end_macro
.macro pop(%des) # 出栈
lw %des, 0(sp)
addi $sp, $sp, 4
.end_macro
DFS
(深度优先搜索)
1 |
|
高精度阶乘
这里直接介绍一种时间复杂度较低的算法:
1 |
|
注意
鉴于1也是经常用到的常量,可以维护
$s1
== 1 。一般在
.data
中先申请完所有需要的内存空间再定义宏。在递归入栈时一定要将返回后还要用到的当前状态量全部压入栈中。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Chères étoile!