【问题标题】:C to MIPS Assembly [closed]C 到 MIPS 程序集 [关闭]
【发布时间】:2016-03-19 18:32:06
【问题描述】:

我试图解决这个问题并将其转换为 MIPS 汇编代码 但是书中的答案让我很困惑。所以,谁能解释这段代码是如何在 c 中得到这个结果的?

B[g] = A[f] + A[f+1];

我已经插入了我认为正确的 cmets,如果我错了,请纠正我。

假设我们有变量 f、g、h、i、j 分别存储在 $s0、$s1、$s2、$s3 和 $s4 中。假设数组 A 和 B 的基地址分别为 $s6 和 $s7。

代码:

add $t0, $s6, $s0  #This will add f bytes to the base address and it's not equal to A[f].
add $t1, $s7, $s1  #This will add g bytes to the base address and it's not equal to B[g]
lw $s0, 0($t0)     #This will point to the value in (f +base address of A +0) bytes
lw $t0, 4($t0)     #This will point to the value in (f +base address of A +4) bytes
add $t0, $t0, $s0  
sw $t0, 0($t1)

【问题讨论】:

  • 在汇编器 sn-p 的 cmets 中是否有错字,其中“不相等”应改为“现在相等”?
  • 这不是“解释我的代码”网站。
  • 你应该问这个问题!正如现在所问的,这个问题显然是题外话。使用编辑链接!
  • @BathantHegazy 我认为代码原样,隐式假设fg 都等于0。

标签: c assembly mips


【解决方案1】:

你的编译片段由我注释:

add $t0, $s6, $s0  

在寄存器t0 中添加并存储寄存器s6s0 中的任何内容。由于您已经指出f 存储在s0 中,A 的基地址存储在s6 中,因此这会添加地址以准备稍后的寄存器间接加载。更简单的是 C 中的 A[f] == *(A + f),这是为稍后的 (A + f) 取消引用做准备。

add $t1, $s7, $s1  

Bg 发生了同样的事情。添加它们的内容并将它们存储在中间寄存器中,稍后用作基于地址的取消引用目标。

lw $s0, 0($t0)     

这是加载到s0 寄存器,使用cpu 的register-indirect 寻址模式,无论t0 指向的地址加上0 个字节。在 c 中,这等于 s0 = *(A + f)

lw $t0, 4($t0)     

和上面一样,只是这次它加载到注册t0 任何指向t0 加上4 个字节。等于 Ct0 = *(A + f + 1)

add $t0, $t0, $s0  

这是它在您的代码中执行加法的地方。相当于A[f] + A[f + 1]的C代码片段。

sw $t0, 0($t1)

这是存储先前添加到t1指向的地址的结果。

~~~~~~~~~~~~~~

如果您正在寻找您拥有的代码的一些参考资料,我找到了MIPS instruction set reference useful,当然还有Matt Godbolt's interactive compiler

如果您想查看使用交互式编译器执行什么代码,只需将您的代码包装在 void 函数中,选择编译器 x86 clang 和编译器选项 --target=mips。然后从过滤器中应用 colourise,您将能够看到哪些 C 代码生成了哪些汇编代码,得到如下图所示的内容

【讨论】:

    【解决方案2】:
    add $t0, $s6, $s0  # t0 = A + f
    add $t1, $s7, $s1  # t1 = B + g
    lw $s0, 0($t0)     # s0 = *(t0 + 0) = *(A + f) = A[f]
    lw $t0, 4($t0)     # t0 = *(t0 + 4) = *(A + f + 1) = A[f+1]
    add $t0, $t0, $s0  # t0 = t0 + s0 = A[f] + A[f+1]
    sw $t0, 0($t1)     # *(t1 + 0) = *(B + g) = B[g] = t0
    

    请记住,C 指针算术按项目大小缩放,但汇编使用字节。因此,推进 4 个字节就是推进 C 中的 1 个项目。

    再想一想,这实际上意味着 fg 也应该按 4 缩放,但它们似乎不是。

    【讨论】:

    • 这意味着这个解决方案是错误的,因为它们必须缩放 4 才能获得偏移量?并感谢您提供帮助:)。
    • 而这个 lw $s0, 0($t0) 将不等于 A[f] ?
    【解决方案3】:
    sll $t0, $s0, 2     # $t0 = f * 4
    add $t0, $s6, $t0
    sll $t1, $s1, 2     # $t1 = g * 4
    add $t1, $s7, $t1
    lw $s0, 0($t0)
    lw $t0, 4($t0)
    add $t0, $t0, $s0  
    sw $t0, 0($t1)
    

    是的,代码缺少这两行,您只需将 fg 都缩放 4。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 1970-01-01
      • 2021-09-13
      • 2014-01-24
      • 1970-01-01
      相关资源
      最近更新 更多