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];
不正确。存储前没有负载,只是地址计算/复制。
我对@987654321@ 的回答具有准确的 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 的翻译的主要内容,如果未能解决你的问题,请参考以下文章