如何使我的MIPS程序更高效和可读 这是我试图用转换为MIPS的C++代码 int count_painted(int *wall, int width, int radius, int coord) { int row = (coord & 0xffff0000) >> 16; int col = coord & 0x0000ffff; int value = 0; for (int row_offset = -radius; row_offset <= radius; row_offset++) { int temp_row = row + row_offset; if (width <= temp_row || temp_row < 0) { continue; } for (int col_offset = -radius; col_offset <= radius; col_offset++) { int temp_col = col + col_offset; if (width <= temp_col || temp_col < 0) { continue; } value += wall[temp_row*width + temp_col]; } } return value; } int count\u涂漆(int*wall、int-width、int-radius、int-coord){ int行=(坐标&0xffff0000)>>16; int col=coord&0x0000ffff; int值=0; 对于(int row_offset=-radius;row_offset radius)(bgt,因为它只能更大) 加上$t7、$t1、$t6#int temp_col=col+col_offset; sle$s3、$a1、$t7#返回1,如果宽度为0,则条件为真,我们迭代然后循环 #bgt$a1$t7,循环计数为1,如果语句中包含或在其中(循环2) #bge$t7,0,循环一次计数 # mul$t8、$t5、$a1乘以临时行和宽度,并存储在$t8中 添加$t8、$t8、$t7——添加临时行和宽度的乘积,并将其添加到临时列,并将其存储在临时寄存器$t9中 #t8是墙壁阵列的索引 #临时寄存器用完使用保存的寄存器 sll$s0、$t8、2 添加$s0、$a0、$s0 lw$s1,0($s0)#$s1包含墙[温度行*宽度+温度列] 添加$v0、$v0、$s1 添加$t6.$t6,1#向列偏移量添加1,即循环迭代 j count_paint_for_loop_two#重新启动内部for loop 循环迭代器的计数\u绘制\u: 添加$t3、$t3、1#遍历循环 j计数\u绘制\u循环\u一 循环两个迭代器的计数\u绘制\u: 添加$t6、$t6、1#遍历循环 循环二的j计数 计数\u结束: jr$ra#返回值
我用光了所有的t寄存器,我被迫使用s寄存器来存储临时变量,我希望学习一种更有用的方法来编写我的MIPS代码你试过看C编译器的输出吗?MIPS gcc5.4()没有如何使我的MIPS程序更高效和可读 这是我试图用转换为MIPS的C++代码 int count_painted(int *wall, int width, int radius, int coord) { int row = (coord & 0xffff0000) >> 16; int col = coord & 0x0000ffff; int value = 0; for (int row_offset = -radius; row_offset <= radius; row_offset++) { int temp_row = row + row_offset; if (width <= temp_row || temp_row < 0) { continue; } for (int col_offset = -radius; col_offset <= radius; col_offset++) { int temp_col = col + col_offset; if (width <= temp_col || temp_col < 0) { continue; } value += wall[temp_row*width + temp_col]; } } return value; } int count\u涂漆(int*wall、int-width、int-radius、int-coord){ int行=(坐标&0xffff0000)>>16; int col=coord&0x0000ffff; int值=0; 对于(int row_offset=-radius;row_offset radius)(bgt,因为它只能更大) 加上$t7、$t1、$t6#int temp_col=col+col_offset; sle$s3、$a1、$t7#返回1,如果宽度为0,则条件为真,我们迭代然后循环 #bgt$a1$t7,循环计数为1,如果语句中包含或在其中(循环2) #bge$t7,0,循环一次计数 # mul$t8、$t5、$a1乘以临时行和宽度,并存储在$t8中 添加$t8、$t8、$t7——添加临时行和宽度的乘积,并将其添加到临时列,并将其存储在临时寄存器$t9中 #t8是墙壁阵列的索引 #临时寄存器用完使用保存的寄存器 sll$s0、$t8、2 添加$s0、$a0、$s0 lw$s1,0($s0)#$s1包含墙[温度行*宽度+温度列] 添加$v0、$v0、$s1 添加$t6.$t6,1#向列偏移量添加1,即循环迭代 j count_paint_for_loop_two#重新启动内部for loop 循环迭代器的计数\u绘制\u: 添加$t3、$t3、1#遍历循环 j计数\u绘制\u循环\u一 循环两个迭代器的计数\u绘制\u: 添加$t6、$t6、1#遍历循环 循环二的j计数 计数\u结束: jr$ra#返回值,c++,performance,assembly,mips,cpu-registers,C++,Performance,Assembly,Mips,Cpu Registers,我用光了所有的t寄存器,我被迫使用s寄存器来存储临时变量,我希望学习一种更有用的方法来编写我的MIPS代码你试过看C编译器的输出吗?MIPS gcc5.4()没有sw指令,因此它不会保存/还原任何$s寄存器。不幸的是,我不知道有什么选项可以让GCC使用$t7寄存器名而不是$15。它还将免费使用$at和$v0..1和$a0..3。我看不到你的代码ites$a寄存器。我使用了-march=mips32,因为您使用的是mul指令,而不是传统的mult/mflo。GCC在所有循环之外的整个函数中只使用一
sw
指令,因此它不会保存/还原任何$s
寄存器。不幸的是,我不知道有什么选项可以让GCC使用$t7
寄存器名而不是$15
。它还将免费使用$at
和$v0..1
和$a0..3
。我看不到你的代码ites$a寄存器。我使用了-march=mips32
,因为您使用的是mul
指令,而不是传统的mult
/mflo
。GCC在所有循环之外的整个函数中只使用一个mul
。要添加的mul的强度缩减非常有用。您试过查看C编译器输出吗?MIPS gcc5.4 ()没有sw
指令,因此它不会保存/还原任何$s
寄存器。不幸的是,我不知道有什么选项可以让GCC使用$t7
寄存器名而不是$15
。它还将免费使用$at
和$v0..1
和$a0..3
。我看不到你的代码ites$a寄存器。我使用了-march=mips32
,因为您使用的是mul
指令,而不是传统的mult
/mflo
。GCC在整个函数中,在任何循环之外只使用一个mul
。要添加的mul的强度降低非常有用。
.globl count_painted
count_paint:
#think about moving variables initialized inside to within the for loop
#initializes all variables
li $v0, 0 # int value = 0
li $t0, 0 # int row = 0
li $t1, 0 # int col = 0
li $t2, 0 # int i = 0
li $t3, 0 # int row _offset = 0
li $t4, -1 # negative one to multiply with row_offset
li $t5, 0 # int temp_row = 0
li $t6, 0 # int col_offset = 0
li $t7, 0 # int temp_col = 0
andi $t0, $a3, 0xffff0000
srl $t0, $t0, 16 # now int row = (coord & 0xffff0000) >> 16 (double check this...prob need a temp register to store before modifying both)
andi $t1, $a3, 0x0000ffff # now int col = coord & 0x0000ffff
mul $t3 , $a2, $t4. # row_offsett = -1 * radius
mul $t6 , $a2, $t4. # col_offsett = -1 * radius
#for loop 1
count_paint_for_loop_one:
bgt $t3, $a2, count_painted_end # if row_offset > radius (bgt since it can only be greater)
add $t5, $t0, $t3 # int temp_row = row + row_offset;
sle $t9, $a1, $t5 # returns 1 if width <= temp_row is true
slt $s2, $t5, 0 # returns 1 if temp_row < 0 is true
or $t9, $t9, $s2 # or the result of the 2 if statment functions
bgt $t9, 0, count_paint_for_loop_one_iterator #if 1 > 0 then condition is true and we iterate and then loop
j count_paint_for_loop_two
#iterator
add $t3, $t3, 1 # adds 1 to row_offset i.e iterates for loop
#dont forget to do the ++ for all iterators
count_paint_for_loop_two:
bgt $t6, $a2, count_paint_for_loop_one # if col_offset > radius (bgt since it can only be greater)
add $t7, $t1, $t6 # int temp_col = col + col_offset;
sle $s3, $a1, $t7 # returns 1 if width <= temp_colis true
slt $s4, $t7, 0 # returns 1 if temp_col < 0 is true
or $s3, $s3, $s4 # or the result of the 2 if statment functions
bgt $s3, 0, count_paint_for_loop_two_iterator #if 1 > 0 then condition is true and we iterate and then loop
#bgt $a1 $t7, count_paint_for_loop_one #if statement with or inside (for loop 2)
#bge $t7, 0, count_paint_for_loop_one
#
mul $t8, $t5, $a1 # multiplies temp_row and width and stores in $t8
add $t8, $t8, $t7 # adds the product of temp_row and width and adds it to temp_col and stores it in temp register $t9
#t8 is index for wall array
#ran out of temp registers use saved registers
sll $s0, $t8, 2
add $s0, $a0, $s0
lw $s1, 0($s0) # $s1 contains wall[temp_row*width + temp_col]
add $v0, $v0, $s1
add $t6. $t6, 1 # adds 1 to col_offset i.e iterates for loop
j count_paint_for_loop_two # restarts inner for loop
count_paint_for_loop_one_iterator:
add $t3, $t3, 1 #iterate through loop
j count_paint_for_loop_one
count_paint_for_loop_two_iterator:
add $t6, $t6, 1 #iterate through loop
j count_paint_for_loop_two
count_painted_end:
jr $ra # returns value