【问题标题】:C to MIPS translation for 2D array and bitwise operation用于二维数组和按位运算的 C 到 MIPS 转换
【发布时间】:2021-12-02 23:34:55
【问题描述】:

我正在尝试将下面的 C 代码翻译成 MIPS,但不知道如何翻译这部分 m |= c; 上面的 MIPS 代码是什么?

【问题讨论】:

  • grid 是如何声明的?是int grid[N_ROWS][N_COLS] 还是double **grid
  • @tstanisl 它的整数
  • 有什么原因不能自己编译看看吗?
  • 如果您将问题编辑为微不足道且没有详细信息,甚至没有尝试使用 or 指令,预计会被否决。特别是当部分标题(二维数组)甚至不再适用时。也没有指定m 的存储位置(在内存或寄存器中),所以答案可能只是说or $t0, $t0, $t1

标签: arrays c assembly bit-manipulation mips


【解决方案1】:

让我们分解这个语句:

m |= constant;

这在一个称为赋值运算符的类别中,这些扩展如下:

m = m | constant
^   ^
|   |
|   +--- source/read
|
+-- target/written

因此,虽然常规赋值 (=) 仅写入,但这些赋值运算符在左侧读取和写入目标表达式。 (col++ 也是一个读-修改-写操作,可以认为是col += 1col = col + 1)。理解后,这些赋值运算符既方便又简洁,而且还有助于我们不必重复复杂的表达式,例如您示例中的数组索引。

| 运算符代表logical or。在 C 中,此运算符将对两个输入的每一位执行逻辑或运算以产生相同大小的输出,因此对于 4 字节大的 int,将逐个位置执行 32 个单独的“或”运算。

与常量“或”用于设置相应位 - 常量中有 1 时,该位的输出将为 1,常量中有 0 时,该位的输出将是另一个输入的值(在那个位位置)。

这就是说:取m的当前值,然后在常量中进行OR运算,并将该值写入m的新当前值。

MIPS 有一个or 指令和ori 指令。

如果变量m 在寄存器中,这可以在一条指令中完成,假设该常量适合 16 位立即数形式(否则,程序员,在某些情况下是汇编程序,可能会将其转换为分成两个或三个指令,一个或两个额外的以显示完整的常量值,然后是 MIPS 或指令)。 or 指令将为m 提供和定位寄存器。

但是,如果变量 m 在内存中,那么,因为 MIPS 是一个加载/存储机器,我们必须将 m 的副本加载到寄存器中,然后执行 or 操作(如如上所述),然后将其存储回内存中以更新它所在的变量。

数组——更具体地说是它们的所有元素——必须在内存中,所以它们需要这种完整的处理。你已经有一个计算来获取元素的地址。


大多数人会使用移位:sll $t3, $t2, 2 乘以 4,因为这在低端硬件上可能更便宜。

不要忘记在开始时初始化row=0;,而不是依赖模拟器来清除寄存器。

(别忘了增加col++。)

作为一种优化,grid 的la 可以移到循环之外和之前,因为它产生的值在循环执行期间不会改变。 (这称为loop invariant code motion。)如果您这样做,只要仍然需要它,就不要在代码的另一部分破坏$t0

在汇编中还有其他可能的优化,例如在外部循环而不是内部循环中进行第一次乘法(row 乘以列大小),因为在内部循环中,row 变量不会变化,因此对于内部循环的每次执行来说,这是一个常量值。

这些代码运动优化中的每一个都需要使用额外的 CPU 寄存器(在某个循环期间),这也是 MIPS 和其他较新的处理器有这么多寄存器的原因之一。

(进一步优化也可以通过从数组索引更改为指针,然后从重新计算元素的字节地址,到将该地址作为在整个循环中有效的变量来维护。)

一般建议坚持使用$t 寄存器,其中有10 个对于您的代码来说已经足够了。 ($s 寄存器在使用时应该被保存和恢复,它们由进行函数调用的代码使用,所以如果你的循环体有一个函数调用作为它的一部分或作为赋值语句的一部分,我们会为rowcol 选择$s 寄存器,以及我们希望在寄存器中并在函数调用中存活的任何其他内容。)

【讨论】:

  • 在低端硬件上可能更便宜。 - 我希望转变为总是比直接mul 的延迟更低,除了在一些专用 CPU 上设计的时钟非常慢但具有高性能乘法器。 (例如,某些 ARM Cortex-M CPU 可以选择快速乘法器。我忘记了它是否是 1 个周期,但小于 3。)无论如何,您的措辞暗示乘法通常等于成本的变化,这可能不是是的,尤其是没有 OoO exec 来隐藏延迟,即使执行单元的可用性对吞吐量来说不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
  • 2016-03-31
  • 2020-11-04
  • 2010-10-13
  • 1970-01-01
  • 2013-06-21
相关资源
最近更新 更多