MIPS 到 C 的翻译

Posted

技术标签:

【中文标题】MIPS 到 C 的翻译【英文标题】:MIPS to C Translation 【发布时间】:2013-09-23 23:36:17 【问题描述】:

我需要将一些 MIPS 汇编指令翻译成 C 代码。我想我明白了,但这似乎违反直觉。有什么帮助吗?我们将变量 f、g、h、i、j 分别存储在寄存器 $s0、$s1、$s2、$s3 和 $s4 中。数组 A 和 B 的基数分别存储在 $s6 和 $s7 中。 4 字节字。代码中的注释是我自己的。

addi $t0, $s6, 4   # $t0 = A[1]
add $t1, $s6, $0   # $t1 = A[0]
sw $t1, 0($t0)     # $t0 = A[0]
lw $t0, 0($t0)     # $t0 = A[0]
add $s0, $t1, $t0  # f = A[0] + A[0]

我只是觉得我错了。如果我们从不使用 $t0 A[1],为什么要先创建它?

【问题讨论】:

How to understand this basic Assembly Code that seems to be adding two pointers? 对相同的怪异代码进行了正确分析,正确的 cmets 像 &A[0],而不是 A[0] 【参考方案1】:

我认为你完全错了。

addi $t0, $s6, 4 # $t0 = A[1]

在addi之后,寄存器$t0变成了A[1]的内存地址,应该是&A[1],而不是A[1]。要获得 A[1] 的值,您需要在完成 addi 后使用 lw

lw $t0, 0($t0) # $t0 =A[1]

【讨论】:

【参考方案2】:
sw $t1, 0($t0)     # $t0 = A[0]

你已经把这个从后到前了。它是一个商店,所以它使用了:

sw $t1, 0($t0)     # A[1] = $t1

【讨论】:

我不这么认为。我的修改改变了第四行的意思。考虑到这一点,你会得到什么?【参考方案3】:

对前面的答案做一点补充: 存储字意味着您不能再访问 $t1,因为它已复制到内存中。至少你不应该使用 store word 指令中的 $t1 。您应该使用之前的那个 (add $t1, $s6, $0)。这意味着答案是f ( which is in $s0) = &A[0] (base address in register $t1) + A[1] (value of the array with word index 1, which is in register $t0)

【讨论】:

【参考方案4】:

Mnush 的回答不正确。

最后一行是添加 $t1 和 $t0。

$t1 = A[0] 和

$t0 = A[1]。

使用适当的 cmets:

addi $t0, $s6, 4   # $t0 = &A[1]
add $t1, $s6, $0   # $t1 = &A[0]
sw $t1, 0($t0)     # A[0] = A[1]
lw $t0, 0($t0)     # $t0 = A[0]
add $s0, $t1, $t0  # f = A[0] + A[1]

C 代码:

A[1] = A[0];
f = A[0] + A[1];

【讨论】:

正在添加地址。 f = &A[0] + &A[1]。这是没有意义的,并且在 C 中需要强制转换为 (uintptr_t),但实际上是 asm 所做的。 那么这是@PeterCordes 的正确答案吗? A[1] = A[0]; f = (unintptr_t)(&A[0] + &A[1]); 不,您不能在 C 中的两个指针之间使用 +。您必须将至少一个操作数转换为 +,而不是结果。也不,A[1] = A[0]; 不正确。存储前没有负载,只是地址计算/复制。 我对@9​​87654321@ 的回答具有准确的 cmets 和 C 等效项,它们实际上可以编译。它是相同的 asm,但即使在问题中也有正确的 cmets,所以不完全是重复的。【参考方案5】:

实际上你使用 A[1] 两次,如图所示:

寄存器$t0携带第一条指令的数组地址

sw $t1, 0($t0)    #  A[1] = $t1  =>  A[1] = &A[0]

将地址($t0 + 0)的值加载到寄存器$t0中

lw $t0, 0($t0)   # $t0 = A[1]

本质上 =>

$t0 = &A[0]

【讨论】:

【参考方案6】:
    addi $t0, $s6, 4   # $t0 = &A[1]
    add $t1, $s6, $0   # $t1 = &A[0]
    sw $t1, 0($t0)     # A[1] = &A[0]
    lw $t0, 0($t0)     # $t0 = A[1]
    add $s0, $t1, $t0  # f = &A[0] + A[1]

C 代码: f = &A[0] + A[1]

【讨论】:

是的,A[1] 拥有&A[0] 的副本。见How to understand this basic Assembly Code that seems to be adding two pointers?【参考方案7】:

猜猜这是正确的。

A[1] = A[0] 
f= A[1] + A[1]

【讨论】:

以上是关于MIPS 到 C 的翻译的主要内容,如果未能解决你的问题,请参考以下文章

c 到 c++,在翻译中丢失

从 Swift 到 Objective C 后台升级的翻译数据任务功能

如何提高Qemu TCG的速度

C++ 到 PHP 翻译

再推新品双屏翻译机,科大讯飞能否站稳C端江湖?

[SystemVerilog] MIPS架构下的五级流水线CPU设计