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

Mars MIPS 3x3矩阵乘法:将C语言循环代码转换为MIPS汇编

Converting 3x3 Matrix Multiplication C Code to MIPS Assembly (MARS)

Got it, let's break down how to translate your C matrix multiplication code into MIPS assembly that works with the MARS simulator. Since we're dealing with a fixed 3x3 matrix, we can hardcode DIM = 3 to simplify the logic—no need for a variable, which makes the assembly cleaner and faster.

First: Data Section Setup

We'll define our three matrices (a, b, r) in the .data segment. I'll add sample values for a and b so you can test the code, and reserve space for r (we'll initialize its values to 0 in the code as your C snippet does).

.data
    # 3x3 matrix A (sample values)
    a: .word 1, 2, 3
       .word 4, 5, 6
       .word 7, 8, 9
    # 3x3 matrix B (sample values)
    b: .word 10, 11, 12
       .word 13, 14, 15
       .word 16, 17, 18
    # 3x3 result matrix R (initialized to 0 later)
    r: .word 0, 0, 0
       .word 0, 0, 0
       .word 0, 0, 0
    dim: .word 3       # Hardcoded DIM = 3 (optional, but makes code readable)
    newline: .asciiz "\n"
    space: .asciiz " "

Second: Text Section (Main Logic)

This is where we'll implement the three nested loops from your C code. We'll use saved registers ($s0-$s6) to hold loop counters and indices, since they preserve values across function calls (though we're not using functions here, it's good practice).

.text
.globl main
main:
    # Initialize saved registers (save old values first, though main doesn't need it for MARS)
    addi $sp, $sp, -28   # Allocate stack space for 7 saved registers
    sw $s0, 0($sp)
    sw $s1, 4($sp)
    sw $s2, 8($sp)
    sw $s3, 12($sp)
    sw $s4, 16($sp)
    sw $s5, 20($sp)
    sw $s6, 24($sp)

    lw $s3, dim          # $s3 = DIM = 3
    li $s0, 0            # int i = 0; (outer loop counter)
outer_loop:
    bge $s0, $s3, end_outer_loop  # if i >= 3, exit outer loop

    li $s1, 0            # int j = 0; (middle loop counter)
middle_loop:
    bge $s1, $s3, end_middle_loop  # if j >=3, exit middle loop

    # Calculate ri = i * DIM + j
    mul $t0, $s0, $s3    # $t0 = i*3
    add $s4, $t0, $s1    # $s4 = ri = i*3 +j

    # r[ri] = 0;
    la $t1, r            # $t1 = address of r
    sll $t2, $s4, 2      # $t2 = ri *4 (since each word is 4 bytes)
    add $t3, $t1, $t2    # $t3 = &r[ri]
    sw $zero, 0($t3)     # r[ri] = 0

    li $s2, 0            # int k =0; (inner loop counter)
inner_loop:
    bge $s2, $s3, end_inner_loop  # if k >=3, exit inner loop

    # Calculate ai = i*DIM +k
    mul $t0, $s0, $s3
    add $s5, $t0, $s2    # $s5 = ai

    # Calculate bi = k*DIM +j
    mul $t0, $s2, $s3
    add $s6, $t0, $s1    # $s6 = bi

    # Load a[ai] and b[bi]
    la $t1, a
    sll $t2, $s5, 2
    add $t3, $t1, $t2
    lw $t4, 0($t3)       # $t4 = a[ai]

    la $t1, b
    sll $t2, $s6, 2
    add $t3, $t1, $t2
    lw $t5, 0($t3)       # $t5 = b[bi]

    # Multiply a[ai] * b[bi]
    mul $t6, $t4, $t5    # $t6 = a[ai] * b[bi]

    # Load current r[ri] value, add product, store back
    la $t1, r
    sll $t2, $s4, 2
    add $t3, $t1, $t2
    lw $t7, 0($t3)       # $t7 = r[ri]
    add $t7, $t7, $t6    # $t7 = r[ri] + product
    sw $t7, 0($t3)       # r[ri] = updated value

    addi $s2, $s2, 1     # k++
    j inner_loop
end_inner_loop:

    addi $s1, $s1, 1     # j++
    j middle_loop
end_middle_loop:

    addi $s0, $s0, 1     # i++
    j outer_loop
end_outer_loop:

    # Optional: Print the result matrix r to verify
    jal print_matrix

    # Restore saved registers
    lw $s0, 0($sp)
    lw $s1, 4($sp)
    lw $s2, 8($sp)
    lw $s3, 12($sp)
    lw $s4, 16($sp)
    lw $s5, 20($sp)
    lw $s6, 24($sp)
    addi $sp, $sp, 28

    # Exit program
    li $v0, 10
    syscall

# Helper function to print the 3x3 matrix
print_matrix:
    li $t0, 0            # row counter =0
print_row:
    bge $t0, $s3, end_print
    li $t1, 0            # column counter=0
print_col:
    bge $t1, $s3, end_col

    # Calculate index = t0*3 +t1
    mul $t2, $t0, $s3
    add $t2, $t2, $t1
    sll $t2, $t2, 2
    la $t3, r
    add $t3, $t3, $t2
    lw $a0, 0($t3)
    li $v0, 1
    syscall              # print element

    # Print space
    la $a0, space
    li $v0, 4
    syscall

    addi $t1, $t1,1
    j print_col
end_col:
    # Print newline
    la $a0, newline
    li $v0,4
    syscall

    addi $t0, $t0,1
    j print_row
end_print:
    jr $ra

Key Notes to Match Your C Code

  • Loop Counters: $s0 = i, $s1 = j, $s2 = k—directly maps to your C loop variables.
  • Index Calculation: We use mul for integer multiplication (MARS supports this; alternatively, you could use sll + add for *3 since 3=2+1, but mul is more readable).
  • Array Access: Since MIPS uses byte addressing, we multiply indices by 4 (sll $t2, $s4, 2) to get the correct byte offset for word-sized elements.
  • Initialization: We explicitly set r[ri] =0 before the inner loop, just like your C code does.

Testing the Code

When you run this in MARS, it will compute the product of matrices a and b, then print the result matrix. For the sample values I used, the result should be:

84  90  96
201 216 231
318 342 366

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:32:47