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

MIPS汇编迭代乘法程序寄存器传值异常:莫名加28问题排查

问题:MIPS迭代加法模拟乘法程序中被乘数值异常偏移

我正在编写一个用迭代加法模拟乘法的MIPS汇编程序,算法逻辑已完成。首次测试时将被乘数设为50,该值存入$a0后转移到$s0,但最终得到的是十进制78(二进制000001001110),而非预期的十进制50(二进制000000110010),莫名多了28。无法定位问题,附上相关代码、预期输出与实际输出,寻求排查和优化建议。


测试文件代码

.globl main
main:
TEST1: 
    li      $a0,    A
    li      $a1,    BBB
    li      $a2,    6         # n: number of bits 
    jal     ex.3.12 

exit:
    li      $v0,    10
    syscall

ex.3.12实现文件代码

.include "./cs47.macro.asm"
.globl ex.3.12

.text
    li  $a0,    6
    li  $a1,    7
    li  $a2,    4
    jal ex.3.12
    print_reg ($s4)
    exit
      
ex.3.12:     # 
    addi  $sp,  $sp,  -24
    sw    $ra,  ($sp)
    sw    $s0,  4($sp)
    sw    $s1,  8($sp)
    sw    $s2, 12($sp)
    sw    $s3, 16($sp)
    sw    $s4, 20($sp)

    jal     display.title       # xxx
    print_str_literal ("Step Action          Multiplier  Mutiplicand      Product
")
    move    $s0,  $a0           #  A = multiplicand
    subi $s0, $s0, 28
    move    $s1,  $a1           #  B = multiplier
    move    $s2,  $a2           #  N = # bits for display, assume N <= 16
    li      $s4,  0             #  product

# xxx print out the initial vals
   print_str_literal ("0    Inital Vals     " )
   print_triple ($s1, $s0, $s4) # xxx print multiplier multiplicand product
   print_newline ()

loop:
    beq     $s2,    $0,  done    #  if index $s2==0 quit loop

    # xxx print out step numbers
    sub     $t0,  $a2,     $s2  # xxx t0 (step number) = N - s2 (index) 
    addi    $t0,  $t0,     1    # xxx t0 --
    print_reg ($t0)             # xxx t0 (step number) = N - 1 - s2 (index)

    andi    $s3,    $s1, 1       #  s3  = right most bit of multiplier s1.
    beq     $s3,    0,   ZERO    #  if s3 == 0, then jump to ZERO
    beq     $s3 1,   ONE
    
ONE: # addition happens
    addu    $s4,    $s4, $s0       #  if s3 == 1, s4 += s0 (multiplicand)
    print_str_literal ("    Prod=Prod+Mcand ")
    print_triple($s1,$s0,$s4)
    j ABC   
    
ZERO :  # no addition
    print_str_literal ("    lsb=0, no op    " )
    print_triple($s1, $s0, $s4)
    j ABC 
    
ABC: 
               # xxx
    sll     $s0,    $s0,   1        #  shift A (multiplicand) 1 bit to the left
        print_reg ($t0)
        print_str_literal("    Lshift Mcand    ")
        print_triple($s1, $s0, $s4)
        
    srl     $s1,    $s1,   1        #  shift B (multiplier) 1 bit to the right
        print_reg ($t0)
        print_str_literal("    Rshift Mplier   ")
        print_triple($s1, $s0, $s4)
        print_newline ()
        
    addi    $s2,    $s2    -1
    
    j       loop

done:
    move  $t0,  $s4
    print_str_literal("
Result of A*B by iterative addition --> ")
    print_reg($t0)
    
    lw    $ra,    ($sp)
    lw    $s0,  4($sp)
    lw    $s1,  8($sp)
    lw    $s2, 12($sp)
    lw    $s3, 16($sp)
    lw    $s4, 20($sp)
    addi  $sp,  $sp,  24
    
    jr      $ra

预期输出(首行部分)

***********************************************************
  A=50  B=10  N=6
************************************************************
Step Action          Multiplier  Multiplicand      Product
0    Initial Vals    001010      000000110010      000000000000     

实际输出(未减28时,首行部分)

************************************************************
  A=50  B=10  N=6
************************************************************
Step Action          Multiplier  Mutiplicand      Product
0    Initial Vals     001010      000001001110      000000000000  

排查与优化建议

1. 核心问题定位

  • 全局测试代码干扰参数传递:实现文件.text段开头的li $a0,6、jal ex.3.12等代码属于全局执行逻辑,会在main函数前运行,直接覆盖main传入的$a0=50,导致被乘数初始值异常。
  • 指令语法错误:beq $s3 1, ONE不符合MIPS指令格式(缺少逗号),汇编时会生成错误机器码,引发寄存器值异常。
  • 多余修正指令:临时添加的subi $s0, $s0, 28属于无效修正,掩盖了根源问题。

2. 具体修复步骤

  • 删除实现文件中ex.3.12标签前的全局测试代码,避免干扰main的参数传递。
  • 修正指令语法:将beq $s3 1, ONE改为beq $s3, 1, ONE。
  • 移除move $s0, $a0后的subi $s0, $s0, 28指令。
  • 检查display.title、print_triple等宏的实现,确保它们不会意外修改$a0或$s0寄存器。

3. 优化建议

  • 添加参数验证:在ex.3.12函数开头打印$a0的值,确认参数传递是否正确。
  • 统一输出格式:删除ABC块中重复的print_reg ($t0),保证每一步输出格式一致。
  • 增加边界测试:测试0、负数、最大位宽等特殊场景,验证算法鲁棒性。
  • 规范注释:清理无用的xxx注释,添加清晰的逻辑说明,提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 09:00:58