MIPS汇编:复制数组元素至dest时如何保持原序而非逆序?
解决MIPS数组复制逆序问题
问题出在栈的后进先出(LIFO)特性:按正序把src的元素压入栈,弹出时会从最后压入的元素开始取,自然导致dest里的元素逆序。下面提供两种直接的修正方案:
方案一:逆序压栈,正序弹出
从src的最后一个元素开始压入栈,这样栈顶是src的第一个元素,弹出时就能按原顺序存入dest。
完整补充后的代码:
.data n: .word 10 src: .word 0 1 2 3 4 5 6 7 8 9 dest: .space 40 i: .word 0 space: .asciiz " " newline:.asciiz "\n" .text main: la $t0, src lw $t1, i la $t2, dest lw $t4, n jal Function_CopytoStack jal Function_copyfrom_Stack_to_Dest # 打印原数组 la $a0, src lw $a1, n jal print_array li $v0, 4 la $a0, newline syscall # 打印目标数组 la $a0, dest lw $a1, n jal print_array # 退出程序 li $v0, 10 syscall # 逆序将src元素压入栈 Function_CopytoStack: sub $t3, $t4, 1 # t3 = n-1 sll $t3, $t3, 2 # 计算偏移量:(n-1)*4(每个word占4字节) add $t0, $t0, $t3 # t0指向src最后一个元素 loop_push: bge $t1, $t4, end_push # 循环i从0到n-1,i>=n时退出 lw $t5, 0($t0) # 取出当前src元素 addi $sp, $sp, -4 # 栈指针减4,分配栈空间 sw $t5, 0($sp) # 将元素压入栈 addi $t0, $t0, -4 # src指针向前移动一个元素 addi $t1, $t1, 1 # 计数器i自增 j loop_push end_push: jr $ra # 返回主函数 # 正序从栈弹出元素存入dest Function_copyfrom_Stack_to_Dest: lw $t1, i # 重置计数器i为0 la $t2, dest # 重置dest指针到起始位置 loop_pop: bge $t1, $t4, end_pop lw $t5, 0($sp) # 弹出栈顶元素 addi $sp, $sp, 4 # 栈指针加4,释放栈空间 sw $t5, 0($t2) # 将元素存入dest addi $t2, $t2, 4 # dest指针向后移动一个元素 addi $t1, $t1, 1 # 计数器i自增 j loop_pop end_pop: jr $ra # 辅助打印数组函数 print_array: move $t0, $a0 li $t1, 0 print_loop: bge $t1, $a1, print_end lw $a0, 0($t0) li $v0, 1 syscall li $v0, 4 la $a0, space syscall addi $t0, $t0, 4 addi $t1, $t1, 1 j print_loop print_end: jr $ra
方案二:正序压栈,逆序存入dest
保持正序压栈的逻辑,弹出时从dest的最后一个位置开始存储,让逆序弹出的元素对应到dest的逆序位置,最终结果保持原顺序。
修改后的核心函数:
# 正序将src元素压入栈 Function_CopytoStack: loop_push: bge $t1, $t4, end_push lw $t5, 0($t0) # 取出当前src元素 addi $sp, $sp, -4 # 分配栈空间 sw $t5, 0($sp) # 压入栈 addi $t0, $t0, 4 # src指针后移 addi $t1, $t1, 1 # 计数器自增 j loop_push end_push: jr $ra # 逆序将栈元素存入dest Function_copyfrom_Stack_to_Dest: sub $t3, $t4, 1 # t3 = n-1 sll $t3, $t3, 2 # 计算最后一个元素的偏移量 la $t2, dest add $t2, $t2, $t3 # t2指向dest最后一个元素 lw $t1, i # 重置计数器i为0 loop_pop: bge $t1, $t4, end_pop lw $t5, 0($sp) # 弹出栈顶元素 addi $sp, $sp, 4 # 释放栈空间 sw $t5, 0($t2) # 存入dest当前位置 addi $t2, $t2, -4 # dest指针前移 addi $t1, $t1, 1 # 计数器自增 j loop_pop end_pop: jr $ra
两种方案都能让dest保持src的原顺序,你可以根据自己的需求选择其中一种。
内容的提问来源于stack exchange,提问作者Dan X
相关产品推荐
相关产品推荐

