【问题标题】:array and matrix multiplication in mipsmips中的数组和矩阵乘法
【发布时间】:2019-10-22 15:34:21
【问题描述】:

我想将 AX 相乘并与 B 相加。因此,(AX)+B。但是,它不起作用,另外我需要在 A 的结果中找到 max num A 是 5*3 矩阵,B 是 3 的数组,C 也是 5 个数字的数组

我在问如何修复该错误以及我的代码有什么问题 此外,我无法编写在矩阵 A 的结果中找到最大数的代码

错误是这样的: PC=0x00400084 发生异常 数据/堆栈读取中的错误地址:0x10040100 PC=0x00400084 发生异常 数据/堆栈读取中的错误地址:0x10040114

la $s4, matrixA     #s4 set to base address of matrixA
la $s3, vectorX     #s3 set to base address of vectorX
la $s7, vectorB     #s7 set to base address of vectorB
la $s5, shapeA       #s5 set to base address of sizeA
nop
lw $s6, 4($s5)      #s6 set to second val in sizeA (col#)
nop
lw $s5, 0($s5)      #s5 set to first val in sizeA (row#)

lw $t1, 0($s5) # $t1 = 32 (row size/loop end)
li $s0, 0  # i = 0; initialize 1st for loop
L1:  li $s1,0  #j=0;restart2ndforloop
L2:  li $s2,0  #k=0;restart3rdforloop

mul $t2, $s0, $s5 #$t2 = A[row](size of row of B)
addiu $t2, $t2, 0 # $t2 = i * size(row) + 0
sll  $t2, $t2, 2   # $t2 = byte offset of [i][0]
addu $t2, $s7, $t2 # $t2 = byte address of B[i][0]
l.d $f4, 0($t2) # $f4 = 4 bytes of B[i][0]

L3: mul $t0,$s2,$s5   #$t0 = i * A[col](size of row of X)
addiu $t0, $t0, 0 # $t0 = k * size(row) + 0
sll  $t0, $t0, 2   # $t0 = byte offset of X[k][0]
addu $t0, $s3, $t0 # $t0 = byte address of X[k][0]
l.d $f16, 0($t0)   # $f16 = 4 bytes of X[k][0]

mul $t0,$s0,$s5 #$t0 = i * A[row](size of row of A)
addu $t0, $t0, $s2 # $t0 = i * size(row) + k
sll $t0, $t0, 2 # $t0 = byte offset of A[i][k]
addu $t0, $s4, $t0   # $t0 = byte address of A[i][k]
l.d $f18, 0($t0)   # $f18 = 4 bytes of A[i][k]

mul.d $f16, $f18, $f16 # $f16 = y[i][k] * z[k][j]
add.d $f4, $f4, $f16 # $f4=x[i][j] + y[i][k]*z[k][j]

addiu $s2, $s2, 1 # k = k + 1
bne $s2,$t1,L3
s.d $f4, 0($t2)

addiu $s2, $s2, 1 # j = j + 1
bne $s2,$t1,L2
addiu $s0, $s0, 1 # i = i + 1
bne $s0,$t1,L1 #if(i!=32)gotoL1

【问题讨论】:

  • lw $t1, 0($s5) 不正确,因为 $s5 不是地址。可能,根据您的评论,您的意思是move $t1,$s5
  • 我改了,但是没用

标签: assembly mips matrix-multiplication


【解决方案1】:

我绝对看不懂你的代码。您声明要进行矩阵向量乘法,但在您的 cmets 中有“x[i][j] + y[i][k]*z[k][j]”。看到地址计算,感觉你是在处理浮点数,但在代码中,似乎更多的是与双精度数相关....

矩阵向量乘法不需要复杂的地址计算,只需递增指针即可完成。

最好将代码中的循环计数和地址计算分开并反转循环中的测试。

C 代码 b[] += a[][]*x[]

  for(i=0;i<N;i++){
    double r=b[i];
    for(j=0;j<M;j++){
      r+=a[i][j]*x[j];
    }
    b[i]=r;
  }

这可以用指针重写

  pb=&b[0] ;
  pa=&a[0][0];
  for (i=0;i<N;i++){
    px=&x[0];
    r=*pb;
    for (j=O;j<M;j++){
      r = r + *px * *pa;
      px++;
      pa++;
    }
    *pb=r ;
    pb++ ;
  }

还有mips版本,就是后面C代码的直接翻译

        la $s1, matrixA     #s1 set to base address of matrixA pa
        la $s2, vectorB     #s2 set to base address of vectorB pb
        la $s3, vectorX     #s3 set to base address of vectorX px
        # s4 temps for the @vectorX
        la $s5, shapeA      #s5 set to base address of sizeA
        lw $s6, 4($s5)      #s6 set to second val in sizeA (col#)
        lw $s5, 0($s5)      #s5 set to first val in sizeA (row#)

L1:     move $t1,$0         # i=0
        move $s4,$s3        # $s4 == px
        l.d $f0,0($s2)      # f0=r=*pb

L2:     move $t2,$0         # j=0
        l.d $f2,0($s1)      # $f2 *pa=a[i]][j]
        l.d $f4,0($s4)      # $f4 *px=x[j]
        mul.d $f2,$f2,$f4   # a[i][j]*x[j]
        add.d $f0,$f0,$f2   # +b[i]
        addi $t2,$t2,1      # j++
        addi $s1,$s1,8      # pa++
        addi $s4,$s4,8      # px++
        bne  $t2,$s6,L2     # j!=N?->L2

        s.d  $f0,0($s2)     # *pb=r
        addi $s2,$s2,8      # pb++
        addi $t1,$t1,1      # i++
        bne  $t1,$6,L1      # j!=M?->L1

编辑:修复错误(感谢@Peter)

【讨论】:

  • 但它会产生错误解析器)文件 /Users/1nhee/Desktop/stackoverflow.asm li $t1,$s5 # i=M 的第 20 行语法错误
  • @ineedyourhelp:大概那些应该是move,而不是li。我认为只是一个大脑放屁;也许 Alain 首先用 NM 作为汇编时常量而不是寄存器输入来编写它。
  • @Alain: bne 需要 2 个寄存器输入。也许你的意思是bnez(针对$zero 的bne 伪操作)。或者更好的是,在循环外计算一个结束地址并使用bne $s1, $t9, L2do { pa++ } while(pa != endpa) 一样循环,而不需要在循环内减少一个单独的计数器。
  • 另外,@ineedyourhelp 将您的代码的损坏版本发布为未回答。我没有看到他们改变了什么,他们没有说什么异常或在哪里,所以可能应该被删除。 IDK,如果它会改进这个尝试被编辑到问题中的问题,虽然。如果您可以将您的答案更新为组装的东西,这可能是最好的,尽管写一个完整的main: 之后返回可能仍然是留给读者作为练习的东西。
  • @Alain slt $t5,$t2,$t2 bne $t5,$zero,L2 # 我是这样改的,但是错误更多
猜你喜欢
  • 2018-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多