MIPS到C语言的翻译

5

我需要将一些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],为什么要先创建它呢?


如何理解这段看起来是将两个指针相加的基本汇编代码?链接中分享的答案对这段奇怪的代码进行了正确的分析,其中包括了正确的注释,例如 &A[0] 而非 A[0] - Peter Cordes
7个回答

3

我认为你完全误解了。

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

我不这么认为。我的修改改变了第四行的意思。考虑到这一点,你得到了什么? - Jens Björnhager

1
Mnush的答案是不正确的。
最后一行是将$t1和$t0相加。 $t1 = A [0],并且 $t0 = A [1]。
带有适当注释:
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];

1
它正在添加地址。f =&A [0] +&A [1]。这没有意义,在C中需要强制转换为(uintptr_t),但实际上是汇编所做的。 - Peter Cordes
这是正确的答案吗,@PeterCordes?A[1] = A[0]; f = (unintptr_t)(&A[0] + &A[1]); - Nick Gallimore
不,你不能在C语言中在两个指针之间使用+。你必须将至少一个操作数强制转换为+,而不是结果。同样,A[1] = A[0];也是不正确的。在存储之前没有加载,只有地址计算/复制。 - Peter Cordes
我的回答关于如何理解这个看起来是在将两个指针相加的基本汇编代码?,其中包含准确的注释和实际可编译的C语言等效代码。虽然使用了相同的汇编代码,但是通过正确的注释,它甚至不算是重复问题。 - Peter Cordes

1

对之前的回答进行补充: store指令意味着你不能再访问$t1,因为它已经被复制到内存中。至少不应该使用store指令后的$t1。你应该使用之前的$t1 (add $t1, $s6, $0)。这意味着答案是f (在$s0中) = &A[0] (基地址在寄存器$t1) + A[1] (数组中索引为1的值,存储在寄存器$t0中)


1

实际上,您两次使用了 A[1],如下所示:

  • Register $t0 carries the address of the array from the first instruction

    sw $t1, 0($t0)    #  A[1] = $t1  =>  A[1] = &A[0]
    
  • Load the value of the address ($t0 + 0) into register $t0

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

    $t0 = &A[0]
    

0
    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]


1
是的,A[1] 持有 &A[0] 的一个副本。请参见 如何理解这个似乎在将两个指针相加的基本汇编代码? - Peter Cordes

-1

猜测这是正确的。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接