如何将含二维数组的C语言if语句转换为MIPS汇编?
解决C语句转MIPS汇编及数组访问优化问题
一、二维数组arr[i][0]的寻址逻辑
MIPS中二维数组按行优先存储,你声明的arr[100][2]若为4字节int类型,每行占用2*4=8字节。
计算地址的核心公式:
arr[i][0]地址:arr基地址 + i * 8 + 0*4arr[i][1]地址:arr基地址 + i * 8 + 1*4
假设寄存器分配如下:
arr基地址存于$s0- 下标
i存于$s1 - 变量
x存于$s2,y存于$s3 gameOver存于$s4
对应寻址汇编片段:
# 计算第i行起始地址并加载arr[i][0]到$t0 sll $t1, $s1, 3 # i*8(左移3位等价乘8) add $t1, $t1, $s0 # 得到第i行起始地址 lw $t0, 0($t1) # 加载arr[i][0] # 加载arr[i][1]到$t2 lw $t2, 4($t1) # 第i行起始地址+4,直接取第二个元素
二、原if语句的基础汇编实现
利用MIPS的短路求值特性,满足一个条件就直接跳转执行递增,无需检查后续分支:
# 检查第一个条件:x == arr[i][0] && y == arr[i][1] bne $s2, $t0, check_cond2 bne $s3, $t2, check_cond2 j increment_gameover check_cond2: # 检查第二个条件:arr[i][0] == x && arr[i][1] == y-1 bne $t0, $s2, check_cond3 addi $t3, $s3, -1 bne $t2, $t3, check_cond3 j increment_gameover check_cond3: # 检查第三个条件:arr[i][0] == x && arr[i][1] == y+1 bne $t0, $s2, check_cond4 addi $t3, $s3, 1 bne $t2, $t3, check_cond4 j increment_gameover check_cond4: # 检查第四个条件:arr[i][0] == x-1 && arr[i][1] == y addi $t3, $s2, -1 bne $t0, $t3, check_cond5 bne $t2, $s3, check_cond5 j increment_gameover check_cond5: # 检查第五个条件:arr[i][0] == x+1 && arr[i][1] == y addi $t3, $s2, 1 bne $t0, $t3, end_if bne $t2, $s3, end_if j increment_gameover increment_gameover: addi $s4, $s4, 1 # gameOver++ end_if: # 后续代码
三、优化方案(大幅减少代码体积)
原条件可等价转换为:计算dx = arr[i][0] - x、dy = arr[i][1] - y,判断|dx| + |dy|是否为0或1(对应原点、上下左右相邻)。优化后代码逻辑更简洁,占用text段空间更少:
# 计算dx和dy sub $t4, $t0, $s2 # dx = arr[i][0] - x sub $t5, $t2, $s3 # dy = arr[i][1] - y # 计算dx的绝对值(若MIPS不支持abs指令,见下方补充) abs $t6, $t4 # 计算dy的绝对值 abs $t7, $t5 # 计算绝对值之和 add $t8, $t6, $t7 # 判断是否满足条件 bgt $t8, 1, end_if # 和大于1,不满足 j increment_gameover increment_gameover: addi $s4, $s4, 1 end_if: # 后续代码
补充:无abs指令时的绝对值实现
如果你的MIPS环境不支持abs指令,手动实现绝对值计算:
# 计算dx的绝对值 bge $t4, $zero, dx_positive sub $t6, $zero, $t4 j dx_done dx_positive: move $t6, $t4 dx_done: # 计算dy的绝对值 bge $t5, $zero, dy_positive sub $t7, $zero, $t5 j dy_done dy_positive: move $t7, $t5 dy_done:
内容的提问来源于stack exchange,提问作者dominic99
相关产品推荐
相关产品推荐

