(mips64) lw 和 sw 不增加寄存器值
(mips64) lw and sw not adding value to registers
我是 mips 新手,对于家庭作业项目,我们必须将 C 代码转换为 mips64 程序集,然后 运行 使用 winmips64 将其转换。 C代码是这样的:
void fir(int X[], int H[], int Y[], int n, int m)
{
int i, j;
int y0;
for (j=0; j<m; j++){
y0=0;
for (i=0; i<n; i++){
y0+=X[i+j]*H[i];
}
Y[j]=y0;
}
}
我遇到问题的行是 y0+=X[i+j]*H[i]
和 Y[j]=y0
,这是我的尝试:
for2:
beq r7,r3, afterfor2 # for(i=0, i<n, i++)
#making X[i+j]
dadd r8,r5,r7 # i+j stored in r8
dmul r9,r8,r18 #(i+j)*8 to find address stored in r8r9
lw r10, r9(r0) #load x[i+j] to r10
#making H[i]
dmul r11,r18,r7 # 8*i
lw r12,r11(r1) #load h[i] to r12
dmul r13,r10,r12 #x[i+j] * h[i]
dadd r6,r6,r13 #y0 = y0 + x[i+j]*h[i]
daddi r7,r7,1 # i++
j for2 # repeat loop
afterfor2:
dmul r14,r5,r18 #8*j stored to r14
sw r6, r14(r2) #Y[j] = y0
daddi r5,r5,1 #j++
j for1 #go back to start of loop for1
更具体地说,这些行是因为没有值被添加到寄存器 r10,r6
,并且 r12
:
lw r10, r9(r0) #load x[i+j] to r10
lw r12,r11(r1) #load h[i] to r12
sw r6, r14(r2) #Y[j] = y0
winmips64 文档提到我需要对数组使用 store/load 的立即数,但是当我不知道立即数时我应该怎么做,而是值基于添加和乘以索引?它们不需要存储在寄存器中吗?
提前感谢您的帮助
编辑:总共的代码
.data #data segment
X: .word 1,1,1,2,2,3,4,2,1,1,2,3,2,4,8,1 #X[]
H: .word 1,5,1,4,2,1,1,1 #H[]
Y: .space 64 #n*8 = 8*8 = 64 bytes reserved for the y0 results = R2
n: .word 8 #n = 8
m: .word 8 #m = 8
.text
fir: #void fir
ori r15, r0, X #address of X[]
ori r1, r0, H #address of H[]
ori r2, r0, Y #address of Y[]
daddi r3,r3,8 # n = r3 = 8
daddi r4,r4,8 # m = r4 = 8
dadd r5,r0,r0 #set j counter to 0
daddi r18,r0,8
j for1 #go to for1 loop
for1:
beq r5,r4,exit #when j is equal to m loop stops and goes to the exit function
dadd r6,r0,r0 #y0 = r6 = 0
dadd r7,r0,r0 #set i counter to 0 for every loop
bne r5,r4,for2 #go to the nested loop for2
for2:
beq r7,r3, afterfor2 # for(i=0, i<n, i++)
#making X[i+j]
dadd r8,r5,r7 #i+j stored in r8
dmul r9,r8,r18 #(i+j)*8 to find address stored in r9
daddu r9,r9,r15
ld r10,(r9) #load x[i+j] to r10
#making H[i]
dmul r11,r18,r7 #8*i
daddu r11,r11,r1 #adding 8*i to the base address
ld r12,(r11) #load h[i] to r12
dmul r13,r10,r12 #x[i+j] * h[i]
dadd r6,r6,r13 #y0 = y0 + x[i+j]*h[i]
daddi r7,r7,1 # i++
j for2 # repeat loop
afterfor2:
dmul r14,r5,r18 #8*j stored to r14
daddu r14,r14,r2
sd r6,(r14) #Y[j] = y0
daddi r5,r5,1 #j++
j for1 #go back to start of loop for1
exit:
halt #exit program
没有register(register)
这样的寻址方式。您必须先将两个寄存器相加。
例如,代替 lw r12,r11(r1)
,执行:
daddu r11,r11,r1
lw r12,(r11)
请注意,在 lw r10, r9(r0)
的情况下,您可以简单地将其替换为 lw r10, (r9)
,因为 r0
的值已硬连线为 0。
我是 mips 新手,对于家庭作业项目,我们必须将 C 代码转换为 mips64 程序集,然后 运行 使用 winmips64 将其转换。 C代码是这样的:
void fir(int X[], int H[], int Y[], int n, int m)
{
int i, j;
int y0;
for (j=0; j<m; j++){
y0=0;
for (i=0; i<n; i++){
y0+=X[i+j]*H[i];
}
Y[j]=y0;
}
}
我遇到问题的行是 y0+=X[i+j]*H[i]
和 Y[j]=y0
,这是我的尝试:
for2:
beq r7,r3, afterfor2 # for(i=0, i<n, i++)
#making X[i+j]
dadd r8,r5,r7 # i+j stored in r8
dmul r9,r8,r18 #(i+j)*8 to find address stored in r8r9
lw r10, r9(r0) #load x[i+j] to r10
#making H[i]
dmul r11,r18,r7 # 8*i
lw r12,r11(r1) #load h[i] to r12
dmul r13,r10,r12 #x[i+j] * h[i]
dadd r6,r6,r13 #y0 = y0 + x[i+j]*h[i]
daddi r7,r7,1 # i++
j for2 # repeat loop
afterfor2:
dmul r14,r5,r18 #8*j stored to r14
sw r6, r14(r2) #Y[j] = y0
daddi r5,r5,1 #j++
j for1 #go back to start of loop for1
更具体地说,这些行是因为没有值被添加到寄存器 r10,r6
,并且 r12
:
lw r10, r9(r0) #load x[i+j] to r10
lw r12,r11(r1) #load h[i] to r12
sw r6, r14(r2) #Y[j] = y0
winmips64 文档提到我需要对数组使用 store/load 的立即数,但是当我不知道立即数时我应该怎么做,而是值基于添加和乘以索引?它们不需要存储在寄存器中吗?
提前感谢您的帮助
编辑:总共的代码
.data #data segment
X: .word 1,1,1,2,2,3,4,2,1,1,2,3,2,4,8,1 #X[]
H: .word 1,5,1,4,2,1,1,1 #H[]
Y: .space 64 #n*8 = 8*8 = 64 bytes reserved for the y0 results = R2
n: .word 8 #n = 8
m: .word 8 #m = 8
.text
fir: #void fir
ori r15, r0, X #address of X[]
ori r1, r0, H #address of H[]
ori r2, r0, Y #address of Y[]
daddi r3,r3,8 # n = r3 = 8
daddi r4,r4,8 # m = r4 = 8
dadd r5,r0,r0 #set j counter to 0
daddi r18,r0,8
j for1 #go to for1 loop
for1:
beq r5,r4,exit #when j is equal to m loop stops and goes to the exit function
dadd r6,r0,r0 #y0 = r6 = 0
dadd r7,r0,r0 #set i counter to 0 for every loop
bne r5,r4,for2 #go to the nested loop for2
for2:
beq r7,r3, afterfor2 # for(i=0, i<n, i++)
#making X[i+j]
dadd r8,r5,r7 #i+j stored in r8
dmul r9,r8,r18 #(i+j)*8 to find address stored in r9
daddu r9,r9,r15
ld r10,(r9) #load x[i+j] to r10
#making H[i]
dmul r11,r18,r7 #8*i
daddu r11,r11,r1 #adding 8*i to the base address
ld r12,(r11) #load h[i] to r12
dmul r13,r10,r12 #x[i+j] * h[i]
dadd r6,r6,r13 #y0 = y0 + x[i+j]*h[i]
daddi r7,r7,1 # i++
j for2 # repeat loop
afterfor2:
dmul r14,r5,r18 #8*j stored to r14
daddu r14,r14,r2
sd r6,(r14) #Y[j] = y0
daddi r5,r5,1 #j++
j for1 #go back to start of loop for1
exit:
halt #exit program
没有register(register)
这样的寻址方式。您必须先将两个寄存器相加。
例如,代替 lw r12,r11(r1)
,执行:
daddu r11,r11,r1
lw r12,(r11)
请注意,在 lw r10, r9(r0)
的情况下,您可以简单地将其替换为 lw r10, (r9)
,因为 r0
的值已硬连线为 0。