You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确将MIPS汇编代码foo2转换为规范C代码?

MIPS汇编foo2转C代码的修正

原MIPS汇编代码

.global foo2
foo2: addi $t0,$zero,0
addi $t2,$zero,2

l1: slt $t6,$t0,$a1
beq $t6,$zero,e1
addi $t1,$zero,2

l2: slt $t6,$t1,$t2
beq $t6,$zero,e2
div $t2,$t1
mflo $t6
mul $t6,$t6,$t1
bne $t6,$t2,e3
addi $t1,$zero,2
addi $t2,$t2,1
j l2

e3: addi $t1,$t1,1
j l2

e2: sll $t6,$t0,2
add $t6,$t6,$a0
sw $t2,0($t6)
addi $t0,$t0,1
addi $t2,$t2,1
j l1

e1: sll $t6,$t0,2
add $t6,$t6,$a0
addi $t0,$zero,0
sw $t0,0($t6)
jr $ra

原C代码的逻辑偏差

原C代码用内层for循环时,会强制每次循环后自增j,这和汇编逻辑完全不符:

void foo2(int* lst, int n) {
    int i, j;
    int next = 2;

    for (i = 0; i < n; i++) {
        for (j = 2; j < next; j++) {
            if ((next / j) * j == next) {
                j = 2;
                next++;
            }
        }
        lst[i] = next;
        next++;
    }
    lst[i] = 0;
}

汇编中bne $t6,$t2,e3的逻辑是:只有当(next/j)*j != next时,才会跳转到e3执行j自增;如果(next/j)*j == next,则重置j为2、next加1,且不执行j的自增,直接回到循环开头重新检查。

修正后的C代码

改用while循环精准匹配汇编的分支逻辑:

void foo2(int* lst, int n) {
    int i = 0;
    int next = 2;

    // 外层循环:生成n个质数存入数组
    while (i < n) {
        int j = 2;
        // 内层循环:检查next是否为质数
        while (j < next) {
            if ((next / j) * j == next) {
                // next能被j整除,不是质数,重置j并检查下一个数
                j = 2;
                next++;
            } else {
                // 不能整除,继续检查下一个j
                j++;
            }
        }
        // 找到质数,存入数组
        lst[i] = next;
        i++;
        next++;
    }
    // 数组末尾存入0
    lst[i] = 0;
}

逻辑对应说明

  • 外层while(i < n)对应汇编的l1循环,$t0对应变量i,$a1对应参数n
  • 内层while(j < next)对应汇编的l2循环,$t1对应变量j,$t2对应变量next
  • 当(next/j)*j == next时,对应汇编中bne不触发,执行重置j为2、next自增后跳回l2
  • 当不相等时,跳转到e3执行j自增后跳回l2
  • 内层循环结束(j >= next)时,说明next是质数,存入数组后i和next自增,回到外层循环
  • 外层循环结束后,给数组末尾赋值0,对应汇编的e1部分

内容的提问来源于stack exchange,提问作者First_1st

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:34:50