MIPS中使用数组
1.一维数组
数组存储需要申请内存空间
.data
array: .space 40 # 存储这些数需要用到数组,数组需要使用 10 * 4 = 40 字节
# 一个 int 整数需要占用 4 个字节,需要存储 10 个 int 整数
# 因此,array[0] 的地址为 0x00,array[1] 的地址为 0x04
# array[2] 的地址为 0x08,以此类推。
str: .asciiz "The numbers are:\n"
space: .asciiz " "
.text
li $v0,5
syscall # 输入一个整数
move $s0, $v0 # $s0 is n
li $t0, 0 # $t0 循环变量
loop_in:
beq $t0, $s0, loop_in_end # $t0 == $s0 的时候跳出循环
li $v0, 5
syscall # 输入一个整数
sll $t1, $t0, 2 # $t1 = $t0 << 2,即 $t1 = $t0 * 4
sw $v0, array($t1) # 把输入的数存入地址为 array + $t1 的内存中
addi $t0, $t0, 1 # $t0 = $t0 + 1
j loop_in # 跳转到 loop_in
loop_in_end:
la $a0, str
li $v0, 4
syscall # 输出提示信息
li $t0, 0
loop_out:
beq $t0, $s0, loop_out_end
sll $t1, $t0, 2 # $t1 = $t0 << 2,即 $t1 = $t0 * 4
lw $a0, array($t1) # 把内存中地址为 array + $t1 的数取出到 $a0 中
li $v0, 1
syscall # 输出 $a0
la $a0, space
li $v0, 4
syscall # 输出一个空格
addi $t0, $t0, 1
j loop_out
loop_out_end:
li $v0, 10
syscall # 结束程序
2.二维数组
.data
matrix: .space 256 # int matrix[8][8] 8*8*4 字节
# matrix[0][0] 的地址为 0x00,matrix[0][1] 的地址为 0x04,……
# matrix[1][0] 的地址为 0x20,matrix[1][1] 的地址为 0x24,……
# ……
str_enter: .asciiz "\n"
str_space: .asciiz " "
# 这里使用了宏,%i 为存储当前行数的寄存器,%j 为存储当前列数的寄存器
# 把 (%i * 8 + %j) * 4 存入 %ans 寄存器中
.macro getindex(%ans, %i, %j)
sll %ans, %i, 3 # %ans = %i * 8
add %ans, %ans, %j # %ans = %ans + %j
sll %ans, %ans, 2 # %ans = %ans * 4
.end_macro
.text
li $v0, 5
syscall
move $s0, $v0 # 行数
li $v0, 5
syscall
move $s1, $v0 # 列数
# 这里使用了循环嵌套
li $t0, 0 # $t0 是一个循环变量
in_i: # 这是外层循环
beq $t0, $s0, in_i_end
li $t1, 0 # $t1 是另一个循环变量
in_j: # 这是内层循环
beq $t1, $s1, in_j_end
li $v0, 5
syscall # 注意一下下面几行,在 Execute 页面中 Basic 列变成了什么
getindex($t2, $t0, $t1) # 这里使用了宏,就不用写那么多行来算 ($t0 * 8 + $t1) * 4 了
sw $v0, matrix($t2) # matrix[$t0][$t1] = $v0
addi $t1, $t1, 1
j in_j
in_j_end:
addi $t0, $t0, 1
j in_i
in_i_end:
# 这里使用了循环嵌套,和输入的时候同理
li $t0, 0
out_i:
beq $t0, $s0, out_i_end
li $t1, 0
out_j:
beq $t1, $s1, out_j_end
getindex($t2, $t0, $t1)
lw $a0, matrix($t2) # $a0 = matrix[$t0][$t1]
li $v0, 1
syscall
la $a0, str_space
li $v0, 4
syscall # 输出一个空格
addi $t1, $t1, 1
j out_j
out_j_end:
la $a0, str_enter
li $v0, 4
syscall # 输出一个回车
addi $t0, $t0, 1
j out_i
out_i_end:
li $v0, 10
syscall
事实上,在做矩阵转化一题时,我用了利用一维数组模拟二维数组
.data
array: .space 10000
space: .asciiz " "
enter: .asciiz "\n"
.text
li $v0,5 # n
syscall
move $t0,$v0
addu $a1,$t0,$zero # a1 is row_counter
li $v0,5 # m
syscall
move $t1,$v0
addu $a2,$t1,$zero # a2 is col_counter
add $a3,$a2,$zero # calcultate row and col
li $t2,0 # i
mult $t0, $t1
mflo $t3 # m*n
input:
beq $t2, $t3, output
li $v0,5
syscall
sll $t4, $t2, 2
sw $v0, array($t4)
addi $t2, $t2, 1
j input
output:
beq $t3, $zero, output_end
beq $a3,$zero,if_1_else # equals to 1 col ; row--
sll $t4,$t3,2
subi $t4,$t4,4
lw $t5, array($t4)
beq $t5,$zero,if_2_else
add $a0,$a1,$zero
li $v0,1
syscall
la $a0,space
li $v0,4
syscall
add $a0,$a3,$zero
li $v0,1
syscall
la $a0,space
li $v0,4
syscall
add $a0,$t5,$zero
li $v0,1
syscall
la $a0,enter
li $v0,4
syscall
subi $a3,$a3,1
subi $t3,$t3,1
j output
if_1_else: # row-- col_reset
subi $a1,$a1,1
add $a3,$zero,$a2
j output
if_2_else:
subi $a3,$a3,1
subi $t3,$t3,1
j output
output_end:
li $v0,10
syscall