将 C for 循环的逻辑分解成我可以在 MIPS 中实现的东西? (计算数组中出现的次数)

Break down the logic for a C for-loop into something I can implement in MIPS? (count number occurrences in an array)

大家好,我正在将我的 C 代码转换为 MIPS,但问题是我无法为此做出正确的逻辑

for (int i=0;i<count;i++)
  {
        h[a[i]]++;
  }

到目前为止我自己的逻辑是错误的

假设

a[]=$t1 b[]=$t2

li $s1,0

for:
bgt $s1,[size of array],end

lw $t3,($t1)
la $t1,4($t3)
lw $t4,($t2)
la $t2,4($t2)
sw $t3,0($t4)

add $s1,$s1,1
j for

我知道这是错误的..但在 MIPS 中它给我错误的地址错误和异常 7 和 4 错误


此外,如何将数组长度存入 MIPS 寄存器,例如 C 如何在不进行硬编码的情况下为您计算元素的数量?

int arr[]={1,3,5,7,9};
int n=sizeof(arr)/sizeof(arr[0]);

您需要了解递增的内容。获得这种理解的一种方法是分解:可以使用 Three-Address Code.

等方法分解表达式

那么建议分解一下:

    h[a[i]]++;

如下:

    int av = a[i];
    h[av]++;

在这种方法中,我们将表达式的各种操作和元素分离到它们自己的代码行中,并使用引入的变量(也称为临时变量或 short-lived 变量)重新连接它们。

我们可以继续分解:

    int av = a[i];

    // decompose h[av]++;
    int *hp = h + av; 
    *hp = *hp + 1;

但仍然:

    int av = a[i];

    int *hp = h + av;

    // decompose *hp = *hp + 1;
    int  hv = *hp;
    hv++;
    *hp = hv;

这已经是分解得差不多了。希望您可以 (1) 将其转化为 MIPS 汇编 (2) 学习分解技术。


注意在C语言中,当一个数组,aint个元素时,在a + ih + j等表达式中有一个隐藏的乘法索引(ij)的 sizeof(int),即 4,称为加法之前发生的缩放 — 这种缩放在 C 中是自动的,必须在汇编中显式完成。


控制结构,即结构化语句也可以分解:

for (i = 0; i < count; i++) {
    ???
}

第一次分解:

i = 0;
while (i < count) {
    ???
    i++;
}

进一步进入 if-goto-label 风格:

    i = 0;
loop1:
    if (i >= count) goto endLoop1;
    ???
    i++;
    goto loop1;
endLoop1:

注意循环退出条件是如何反转(否定)的——这是因为在 if-goto-label 中,我们写的是何时退出循环而不是像 C for/while 中那样何时继续循环,正好相反。

(情况并非总是如此:do-while 条件也说明何时继续循环,并且在汇编中,因为这是为下一次迭代放置向后分支的自然位置循环,do-while 和 if-goto-label 版本的条件测试将具有相同的条件意义——它们不是相反的——而 repeat-until in Pascal 使用相反的条件意义。)

另外 NB< 的 inversion/negation/opposite 是 >=


分解是通过逻辑等价的变换来简化。只要我们保持逻辑等价,分解就会运行和原来一样。