求助:在MARS环境下的MIPS中创建动态数组存储矩阵第3行元素
MIPS汇编:动态数组创建与矩阵行元素迁移解决方案
核心问题:任务6实现说明
要完成创建动态数组new并存储mymat第3行元素的需求,核心步骤如下:
- 动态内存分配:使用MIPS的
syscall 9(sbrk)申请内存,8个float元素共需8*4=32字节,分配后的内存基地址存入寄存器(如$s0)。 - 定位目标行:静态矩阵按行连续存储,每行8个float(32字节),第3行(从1开始计数)的起始偏移为
(3-1)*32=64字节,对应mymat+64的位置。 - 元素复制循环:逐个加载第3行的float元素,存储到动态分配的内存中,每次偏移增加4字节(float的字节长度)。
完整修正代码
.data # 6×8静态浮点矩阵初始化 mymat: .float 1.1,2,3,4,5,6,7,8 .float 9,10,11,12,13,14,15,16 .float 17,18,19,20,21,22,23,24 # 第3行(从1计数) .float 25,26,27,28,29,30,31,32 .float 33,34,35,36,37,38,39,40 .float 41,42,43,44,45,46,47,48 # 分隔符与提示字符串 colon_sep: .asciiz "::" dollar_sep: .asciiz "$$" star_sep: .asciiz "*" newline:.asciiz "\n" prompt_col1: .asciiz "请输入第一个列号(0-7): " prompt_col2: .asciiz "请输入第二个列号(0-7): " invalid_input: .asciiz "输入非法,请重新输入!\n" .text .globl main main: ####################### 任务2:打印初始矩阵(::分隔) li $t0, 1 # 已打印元素计数 li $t1, 0 # 数组字节偏移 li $t4, 8 # 每行元素数 print_initial_loop: bgt $t0, 48, get_columns # 48个元素打印完成,进入任务3 # 打印当前浮点元素 l.s $f12, mymat($t1) li $v0, 2 syscall # 判断是否为行末,避免多余分隔符 div $t0, $t4 mfhi $t3 bne $t3, 0, print_colon # 行末打印换行 la $a0, newline li $v0, 4 syscall j initial_loop_end print_colon: la $a0, colon_sep li $v0, 4 syscall initial_loop_end: add $t1, $t1, 4 # 偏移+4(float占4字节) add $t0, $t0, 1 # 计数+1 j print_initial_loop ####################### 任务3:获取并验证列号输入 get_columns: get_col1: la $a0, prompt_col1 li $v0, 4 syscall li $v0, 5 # 读取整数 syscall move $s1, $v0 # $s1 = col1 # 验证0<=col1<=7 bltz $s1, col1_invalid bgt $s1, 7, col1_invalid j get_col2 col1_invalid: la $a0, invalid_input li $v0, 4 syscall j get_col1 get_col2: la $a0, prompt_col2 li $v0, 4 syscall li $v0, 5 syscall move $s2, $v0 # $s2 = col2 bltz $s2, col2_invalid bgt $s2, 7, col2_invalid j swap_columns col2_invalid: la $a0, invalid_input li $v0, 4 syscall j get_col2 ####################### 任务4:交换两列元素 swap_columns: sll $s1, $s1, 2 # 列号转字节偏移(*4) sll $s2, $s2, 2 li $t0, 0 # 行计数器(0-5,共6行) li $t3, 32 # 每行字节数(8*4) swap_loop: bge $t0, 6, print_swapped # 6行处理完成 # 计算当前行两列的地址偏移 mul $t1, $t0, $t3 # 行起始偏移 add $t4, $t1, $s1 # col1地址 add $t5, $t1, $s2 # col2地址 # 交换元素 l.s $f0, mymat($t4) l.s $f2, mymat($t5) s.s $f2, mymat($t4) s.s $f0, mymat($t5) addi $t0, $t0, 1 j swap_loop ####################### 任务5:打印交换后的矩阵($$分隔) print_swapped: la $a0, newline li $v0, 4 syscall # 换行分隔两个矩阵 li $t0, 1 li $t1, 0 swap_print_loop: bgt $t0, 48, create_dynamic_array l.s $f12, mymat($t1) li $v0, 2 syscall div $t0, $t4 mfhi $t3 bne $t3, 0, print_dollar la $a0, newline li $v0, 4 syscall j swap_print_end print_dollar: la $a0, dollar_sep li $v0, 4 syscall swap_print_end: add $t1, $t1, 4 add $t0, $t0, 1 j swap_print_loop ####################### 任务6:创建动态数组并存储第3行元素 create_dynamic_array: li $a0, 32 # 申请32字节(8个float) li $v0, 9 # syscall 9: sbrk动态分配内存 syscall move $s0, $v0 # $s0 = 动态数组基地址 li $t0, 0 # 元素计数器(0-7) li $t1, 64 # 第3行起始偏移:(3-1)*32=64字节 li $t2, 0 # 动态数组偏移 copy_row_loop: bge $t0, 8, print_dynamic_array # 复制单个元素 l.s $f0, mymat($t1) s.s $f0, ($s0, $t2) # 更新偏移与计数器 addi $t1, $t1, 4 addi $t2, $t2, 4 addi $t0, $t0, 1 j copy_row_loop ####################### 任务7:打印动态数组(*分隔) print_dynamic_array: la $a0, newline li $v0, 4 syscall # 新行开头 li $t0, 0 li $t1, 0 dynamic_print_loop: bge $t0, 8, exit_program l.s $f12, ($s0, $t1) li $v0, 2 syscall # 避免最后一个元素后打印* bge $t0, 7, dynamic_print_end la $a0, star_sep li $v0, 4 syscall dynamic_print_end: addi $t1, $t1, 4 addi $t0, $t0, 1 j dynamic_print_loop exit_program: li $v0, 10 syscall
关键细节说明
- 动态内存分配:
syscall 9会将分配的内存基地址存入$v0,后续通过基地址+偏移访问动态数组元素。 - 矩阵行定位:若你对“第3行”的计数是从0开始(即1.1所在行为第0行),则起始偏移需改为
3*32=96字节,对应25-32的元素,只需修改create_dynamic_array中的li $t1, 64为li $t1, 96即可。 - 原代码修正:移除了原代码中覆盖矩阵第一个元素的
sw $s0,mymat($t1)语句,避免破坏初始数据。
内容的提问来源于stack exchange,提问作者محمد العرادي
相关产品推荐
相关产品推荐

