You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MIPS汇编中声明以N个整数数组为参数的函数

实现支持任意N个整数的MIPS动态数组

你当前的代码已经能完成固定大小数组的读写和打印,但要支持任意数量的整数,核心问题是静态数组的空间是预先分配好的,无法根据用户输入的N动态调整。解决这个问题的关键是使用MIPS的堆内存动态分配功能(通过syscall 9即sbrk指令)。

原代码各模块展示

原数据段(静态数组)

.data
arr: .space 32    # 预留8个整数的空间(每个整数4字节)
msg: .asciiz "Enter the number of elements to store: "
msg1: .asciiz "Enter an integer value: "

原主程序

.text
main:
    # 打印提示信息
    la $a0, msg
    li $v0, 4
    syscall

    # 读取元素个数
    li $v0, 5
    syscall
    move $s2,$v0
    move $a1,$v0   # 将元素个数存入$a1

    # 加载静态数组地址
    la $a0, arr

    # 调用数组读取函数
    jal read_array_function
    
    move $a0,$v0    # 将返回的数组地址传给打印函数
    move $a1,$s2
    
    jal print_array_function
    
    jal read_array_function
    
    # 结束程序
    li $v0, 10
    syscall

原数组读取函数

read_array_function:
    sub $sp, $sp, 24  # 分配栈空间
    sw $a0, 0($sp)    # 保存数组地址到栈
    sw $a1, 4($sp)    # 保存元素个数到栈
    sw $ra, 8($sp)    # 保存返回地址到栈
    sw $zero, 12($sp) # 初始化循环计数器
    sw $a0, 16($sp)   # 保存数组起始地址用于返回

    lw $t0, 0($sp)    # 从栈加载数组地址
    lw $t1, 4($sp)    # 从栈加载元素个数
    lw $t2, 12($sp)   # 从栈加载循环计数器
    lw $t3, 8($sp)    # 从栈加载返回地址
    lw $t4, 16($sp)   # 从栈加载数组起始地址

read_loop:
    beq $t2, $t1, end_read  # 计数器等于元素个数时退出循环
    
    la $a0,msg1
    li $v0,4
    syscall
    
    # 读取用户输入的整数
    li $v0, 5
    syscall
    # 将输入存入数组
    sw $v0, ($t0)          # 存储到当前数组地址
    addi $t0, $t0, 4      # 移动到下一个元素地址
    addi $t2, $t2, 1      # 递增计数器
    j read_loop            # 循环

end_read:
    lw $ra, 0($sp)    # 恢复返回地址
    addi $sp, $sp, 24 # 恢复栈指针
    move $v0,$t4
    jr $t3           # 返回调用者

原数组打印函数

print_array_function:
    sub $sp,$sp,12      # 分配12字节栈空间
    sw  $a0,0($sp)      # 保存数组地址到栈
    sw  $zero,4($sp)    # 初始化循环计数器为0
    sw  $a1,8($sp)      # 保存元素个数到栈
    
    lw  $t0,0($sp)      # 加载数组地址到$t0
    lw  $t1,4($sp)      # 加载循环计数器到$t1
    lw  $t2,8($sp)      # 加载元素个数到$t2
    
print_loop:
    beq  $t1,$t2,end_print
    lw $a0,($t0)        # 加载当前数组元素
    li $v0,1            
    syscall
    addi $t0,$t0,4      # 移动到下一个元素地址
    addi $t1,$t1,1      # 递增计数器
    j print_loop
    
end_print:
    addi $sp, $sp, 12   # 恢复栈指针
    jr $ra              # 返回调用者

修改为支持任意N个整数的方案

核心修改点:动态分配堆内存

MIPS中可以通过syscall 9(sbrk)向操作系统申请堆内存,根据用户输入的N计算需要的内存大小(每个整数占4字节,所以总大小是N * 4),用这个大小调用sbrk后,$v0会返回分配到的内存起始地址,用这个地址作为数组的基地址即可。

修改后的完整代码

数据段(移除静态数组)

.data
# arr: .space 32    # 不再使用静态数组,改用动态分配
msg: .asciiz "Enter the number of elements to store: "
msg1: .asciiz "Enter an integer value: "

主程序(新增动态内存分配逻辑)

.text
main:
    # 提示输入元素个数
    la $a0, msg
    li $v0, 4
    syscall

    # 读取元素个数N
    li $v0, 5
    syscall
    move $s2, $v0       # 保存N到$s2
    move $a1, $v0       # 将N存入$a1

    # 计算所需内存大小:N * 4字节
    mul $a0, $s2, 4
    li $v0, 9           # syscall 9: sbrk,申请堆内存
    syscall
    move $a0, $v0       # $a0现在是动态数组的起始地址

    # 调用数组读取函数
    jal read_array_function
    
    move $a0, $v0       # 将数组地址传给打印函数
    move $a1, $s2
    
    jal print_array_function

    # 可选:释放堆内存(模拟器中通常不需要,若需释放可执行以下代码)
    # mul $a0, $s2, -4
    # li $v0, 9
    # syscall

    # 结束程序
    li $v0, 10
    syscall

优化后的数组读取函数(简化栈操作)

原读取函数的栈操作有冗余,可简化为:

read_array_function:
    sub $sp, $sp, 16  # 仅分配必要的栈空间(保存$a0, $a1, $ra, 计数器)
    sw $a0, 0($sp)    # 保存数组起始地址
    sw $a1, 4($sp)    # 保存元素个数
    sw $ra, 8($sp)    # 保存返回地址
    sw $zero, 12($sp) # 初始化循环计数器

    lw $t0, 0($sp)    # 当前数组地址
    lw $t1, 4($sp)    # 元素个数
    lw $t2, 12($sp)   # 循环计数器

read_loop:
    beq $t2, $t1, end_read
    
    la $a0, msg1
    li $v0, 4
    syscall
    
    li $v0, 5
    syscall
    sw $v0, ($t0)
    addi $t0, $t0, 4
    addi $t2, $t2, 1
    j read_loop

end_read:
    lw $ra, 8($sp)
    lw $v0, 0($sp)    # 返回数组起始地址
    addi $sp, $sp, 16
    jr $ra

数组打印函数无需修改

原打印函数是基于传入的数组地址和元素个数操作的,和数组的存储位置(静态/动态)无关,所以可以直接沿用。

说明

通过动态分配堆内存,程序可以根据用户输入的N灵活分配对应大小的空间,彻底解决静态数组大小固定的限制。需要注意的是,在MIPS模拟器(比如SPIM、MARS)中,堆内存的管理相对宽松,通常不需要手动释放,但在实际系统中,动态分配的内存使用完后应该释放避免内存泄漏。

内容的提问来源于stack exchange,提问作者Utku Berki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 13:44:55