技术需求:从键盘输入a、b并创建b规模数组,验证嵌套循环代码
分析嵌套循环MIPS汇编代码并验证逻辑
我来帮你拆解这段MIPS嵌套循环代码,顺便教你怎么手动模拟执行来验证逻辑~
首先先把完整的MIPS汇编代码贴出来:
.text .main addi $t0, $zero, -1 #i = -1 for1loop: addi $t0, $t0, 1 #i += 1 slt $t2, $t0, $s0 #i < a beq $t2, $zero, exit #若$t2 == 0,跳转至exit and $t1, $t1, $zero #j = 0 for2loop: slt $t2, $t1, $s1 #j < b beq $t2, $zero, for1loop #若$t2 == 0,跳转至for1loop sll $t4, $t1, 4 #寄存器$t4 = 16 * j (左移4位等价于乘以2^4=16) add $t2, $t0, $t4 #寄存器$t2 = i + 16 * j add $t3, $s2, $t1 #寄存器$t3 = &D[j] ($s2是数组D的基地址) sw $t2, 0($t3) #将$t2存储至$t3指向的地址 addi $t1, $t1, 1 #j += 1 j for2loop #跳转至for2loop exit: li $v0,10 #退出程序代码 syscall #执行系统调用退出程序
代码逻辑逐行拆解
- 外层循环初始化:
addi $t0, $zero, -1把寄存器$t0(对应变量i)初始化为-1,因为外层循环的第一行就是自增1,所以实际循环会从i=0开始。 - 外层循环(for1loop):
addi $t0, $t0, 1:让i自增1,每次迭代先更新循环变量slt $t2, $t0, $s0:判断i < a($s0用来存储你输入的参数a),如果条件成立$t2会被设为1,否则为0beq $t2, $zero, exit:如果i >= a(也就是$t2=0),直接跳转到exit标签退出外层循环
- 内层循环初始化:
and $t1, $t1, $zero把寄存器$t1(对应变量j)清零,也就是j=0,每次外层循环开始都会重置内层循环变量 - 内层循环(for2loop):
slt $t2, $t1, $s1:判断j < b($s1存储输入的参数b),条件成立则$t2=1,否则为0beq $t2, $zero, for1loop:如果j >= b,跳回外层循环的开头,开始下一次迭代sll $t4, $t1, 4:左移4位等价于j * 16(因为2^4=16),所以$t4的值是16*jadd $t2, $t0, $t4:计算i + 16*j,把结果存在$t2里add $t3, $s2, $t1:$s2是数组D的基地址,加上j就得到数组第j个元素的地址(这里假设数组是字节型,因为直接累加j偏移)sw $t2, 0($t3):把计算出来的i+16j存储到数组D的第j个位置addi $t1, $t1, 1:j自增1j for2loop:跳回内层循环开头,继续迭代
- 退出程序:
li $v0,10和syscall是MIPS里标准的退出程序系统调用。
手动模拟验证逻辑
我们拿具体的输入值来模拟,比如输入a=2(存在$s0),b=3(存在$s1),数组D的基地址存在$s2:
- 外层循环i=0:
- j=0:计算
0 + 16*0=0,把0存入D[0]→D[0]=0 - j=1:计算
0 +16*1=16,存入D[1]→D[1]=16 - j=2:计算
0+16*2=32,存入D[2]→D[2]=32 - j=3:此时
j >=b,跳回外层循环
- j=0:计算
- 外层循环i=1:
- j=0:计算
1+0=1,覆盖D[0]→D[0]=1 - j=1:计算
1+16=17,覆盖D[1]→D[1]=17 - j=2:计算
1+32=33,覆盖D[2]→D[2]=33 - j=3:跳回外层循环
- j=0:计算
- 外层循环i=2:此时
i >=a,跳转到exit退出程序
最终数组D的内容是[1, 17, 33],你可以通过这个结果来验证代码逻辑是否符合预期。
内容的提问来源于stack exchange,提问作者Lina Bobali
相关产品推荐
相关产品推荐

