1

这是C中的代码

Void mm ( double a[][]), double b[][], double c[][])
 {
    int i, j, k;
    for (i=0; i! = 3; i = i+1){
        for (j = 0; j! = 3; j = j+1){
            d[i][j] = a[i][j] ;
            for (k = 0; k! = 3; k = k+1){
               d[i][j] = d[i][j] + b[i][k] * c[k][j];
            }
        }
     }
 }

还要记住,我必须读取数组 a、b、c 的数据,然后打印数组 d,这是我的汇编代码

    .data  
arrA:       .space 72
arrB:       .space 72
arrC:       .space 72   
arrD:       .space 72 

bracA:      .asciiz "a("
bracB:      .asciiz "b("
bracC:      .asciiz "c("
bracD:      .asciiz "d("
comma:      .asciiz "," 
endBrac:    .asciiz ")= "
nextLine:   .asciiz "\n"


.text
.globl main

main:

    addi $sp, $sp, -32          #Make space of stack
    sw $ra, 20($sp)             #Store $ra

    la $a1, arrA                #load base of Array a
    la $a2, arrB                #load base of Array b
    la $a3, arrC                #load base of Array c
    la $t7, arrD                #load base of Array d

    li $s0, 1                   #set i
    li $s1, 1                   #set j
    li $s2, 1                   #set k
    li $s7, 1                   #counter


loopi:
    slti $t0, $s0, 4            #Check i<4
    beq  $t0, $zero, nextArr    #If i=4 go nextArr
loopj:
    slti $t0, $s1, 4            #Check j<4
    beq  $t0, $zero, nextRow    #If i=4 go nextRow
    slti $t1, $s7, 4            #Check counter
    beq  $t1, $zero, contB      #if counter >=4 go to contB
    li   $v0, 4                 #Prepare for print string
    la   $a0, bracA             #Load adress of string "a("
    syscall
    j cont
contB:
    slti $t1, $s7, 7
    beq  $t1, $zero, contC      #if counter>=7 go to contC
    li   $v0, 4
    la   $a0, bracB
    syscall
    j cont
contC:
    slti $t1, $s7, 10
    beq  $t1, $zero, calcD
    li   $v0, 4
    la   $a0, bracC
    syscall
cont:
    li   $v0, 1                 #prepare to print integer
    move $a0, $s0               #print i
    syscall
    li   $v0, 4
    la   $a0, comma
    syscall
    li   $v0, 1
    move $a0, $s1               #print j
    syscall
    li   $v0, 4     
    la   $a0, endBrac
    syscall
    sll  $t0, $s0, 1            #t0=2*i
    add  $t0, $t0, $s0          #t0=3*i
    add  $t0, $t0, $s1          #t0=3*i +j
    sll  $t0, $t0, 3            #t0=(3*i +j)*8  create double precision
    slti $t1, $s7, 4
    beq  $t1, $zero, useA2
    add  $t0, $t0, $a1          #a1=base address of a array
    j contLi
useA2:
    slti $t1, $s7, 7
    beq  $t1, $zero, useA3
    add  $t0, $t0, $a2          #a2=base address of a array
    j contLi
useA3:
    add  $t0, $t0, $a3          #a3=base address of a array
contLi:
    li   $v0, 7
    syscall
    s.d   $f0, 0($t0)           #store $t0 to $f0 as floating point
    l.d  $f12, 0($t0)
    li   $v0, 3 #get ready to print double
    syscall
    addi $s1, $s1, 1            #increase j
    li   $v0, 4
    la   $a0, nextLine
    syscall
    j    loopj

nextRow:
    addi $s7, $s7, 1            #increase counter
    addi $s0, $s0, 1            #increase i
    li   $s1, 1                 #set j=1
    j    loopi

nextArr:
    li $s0, 1                   #set i=1
    li $s1, 1                   #set j=1
    j loopi


calcD:  
    li   $s0, 1                 #set i,j,k=1 for calculations
    li   $s1, 1
    li   $s2, 1     
    li   $t0, 0
    li   $t1, 0
    li   $t2, 0
    li   $t3, 0
outLoop:
    slti $t0, $s0, 4            #Loop that count i
    beq  $t0, $zero, printRes
inLoop1:
    slti $t0, $s1, 4            #loop that count j
    beq  $t0, $zero, finInLoop1
    sll  $t0, $s0, 1            #t0=2*i
    add  $t0, $t0, $s0          #t0=3*i
    add  $t0, $t0, $s1          #t0=3*i +j
    sll  $t0, $t0, 3            #t0=(3*i +j)*8 (double precision)
    add  $t0, $t0, $a1          #a1=base address of a array
    sll  $t1, $s0, 1            #t3=2*i
    add  $t1, $t1, $s0          #t3=3*i
    add  $t1, $t1, $s1          #t3=3*i +j
    sll  $t1, $t1, 3            #t3=(3*i +j)*8  for double precision
    add  $t1, $t1, $t7          #t4=base address of d array
    mtc1 $zero,$f0              #f8=sum to be stored in d[i][j](initial value before k loops=0)
    cvt.d.w $f0, $f0
    mov.d $f8, $f0
    l.d   $f2, 0($t0)           #Load $t0 to $f2

inLoop2:
    slti $t4, $s2, 4            #Loop that count k
    beq  $t4, $zero, finInLoop2
    sll  $t2, $s0, 1            #t1=2*i
    add  $t2, $t2, $s0          #t1=3*i
    add  $t2, $t2, $s2          #t1=3*i +k
    sll  $t2, $t2, 3            #t1=(3*i +k)*8 (double precision)
    add  $t2, $t2, $a2          #a2=base address of b array
    sll  $t3, $s2, 1            #t2=2*k
    add  $t3, $t3, $s2          #t2=3*k
    add  $t3, $t3, $s1          #t2=3*k +j
    sll  $t3, $t3, 3            #t2=(3*k +j)*8 for double precision
    add  $t3, $t3, $a3          #a3=base address of c array 

#So far, t0=address of a[i][j], t1=address of b[i][k], t2=address of c[k][j] and t3=address of d[i][j]

    l.d   $f4, 0($t2)           #Load $t2 to $f4
    l.d   $f6, 0($t3)           #Load $t3 to $f6
    mul.d $f10, $f4, $f6
    add.d $f8, $f8, $f10
    addi  $s2, $s2, 1
    j     inLoop2

finInLoop2: 
    add.d $f8, $f8, $f2
    s.d  $f8, 0($t1)#store total sum  in d[i][j]
    addi $s1, $s1, 1
    li   $s2, 1 #k=1 to start loop for next j
    add.d $f8, $f8, $f0
    j    inLoop1
finInLoop1:
    addi $s0, $s0, 1
    li   $s1, 1# j=1 to start loop for next i
    j    outLoop

printRes:
    li $s0, 1 #initial value of i=1
    li $s1, 1 #initial value of j=1
    li $s2, 1 #initial value of k=1

printLoop1:
    slti $t0, $s0, 4
    beq  $t0, $zero, Exit
    slti $t0, $s1, 4
    beq  $t0, $zero, printLoop2
    li   $v0, 4
    la   $a0, nextLine 
    syscall 
    li   $v0, 4
    la   $a0, bracD
    syscall
    li   $v0, 1
    move $a0, $s0
    syscall
    li   $v0, 4
    la   $a0, comma
    syscall 
    li   $v0, 1
    move $a0, $s1
    syscall
    li   $v0, 4
    la   $a0, endBrac
    syscall 
    sll  $t0, $s0, 1   #t0=2*i
    add  $t0, $t0 $s0 #t0=3*i
    add  $t0, $t0, $s1 #t0=3*i +j
    sll  $t0, $t0, 3   #t0=(3*i +j)*8 (double precision)
    add  $t0, $t0, $t7 #t4=base address of d array
    l.d  $f12, 0($t0)
    li   $v0, 3 #get ready to print double
    syscall
    addi $s1, $s1, 1
    j    printLoop1

printLoop2:
    addi $s0, $s0, 1
    li   $s1, 1
    j    printLoop1

Exit:
    jr $ra

当我读取数据时,程序会立即打印出我所写的内容,但最终不会打印 d 数组 我是 mips 汇编的初学者,所以我的代码可能存在一些重大问题,但我找不到它们...

4

0 回答 0