5

I need to translate some MIPS assembly instructions to C code. I think I got it, but it seems counter-intuitive. Any help? We have variables f, g, h, i, j stored in registers $s0, $s1, $s2, $s3 and $s4 respectively. The base of arrays A and B are stored in $s6 and $s7 respectively. 4 byte words. Comments in the code are my own.

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]

I just feel like I'm wrong. Why make $t0 A[1] first if we never use it?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
user2789564
  • 75
  • 1
  • 2
  • 6
  • [How to understand this basic Assembly Code that seems to be adding two pointers?](https://stackoverflow.com/a/66807155) has correct analysis of the same weird code, with correct comments like `&A[0]`, not `A[0]`. – Peter Cordes Mar 25 '21 at 20:45

7 Answers7

3

I think you have got in completely wrong.

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

After the addi, register $t0 became the memory address of A[1], which would be &A[1], not A[1]. To get value of A[1], you need to use lw after you done the addi

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

TheCyberliem
  • 1,178
  • 12
  • 14
2
sw $t1, 0($t0)     # $t0 = A[0]

You've got this back-to-front. It is a store, so it is used:

sw $t1, 0($t0)     # A[1] = $t1
Jens Björnhager
  • 5,632
  • 3
  • 27
  • 47
1

Just a little addition to the previous answers: The store word means that you cannot access $t1 anymore because it is copied to memory. At least you should not use the $t1 from the store word instruction. You should use the one before (add $t1, $s6, $0). This means that the answer is 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)

Hiltje
  • 140
  • 1
  • 5
1

Mnush's answer is incorrect.

The last line is adding $t1 and $t0.

$t1 = A[0] and

$t0 = A[1].

With proper comments:

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]

The C Code:

A[1] = A[0];
f = A[0] + A[1];
Nick Gallimore
  • 1,222
  • 13
  • 31
  • 1
    It's adding addresses. `f = &A[0] + &A[1]`. This makes no sense, and in C would require casts to `(uintptr_t)`, but is what the asm actually does. – Peter Cordes Sep 23 '20 at 15:52
  • So is this the correct answer @PeterCordes? `A[1] = A[0]; f = (unintptr_t)(&A[0] + &A[1]);` – Nick Gallimore Nov 19 '20 at 14:35
  • No, you can't `+` between two pointers in C. You have to cast at least one of the operands to `+`, not the result. Also no, `A[1] = A[0];` isn't correct. There's no load before the store, just address calculations / copies. – Peter Cordes Nov 19 '20 at 14:59
  • My answer on [How to understand this basic Assembly Code that seems to be adding two pointers?](https://stackoverflow.com/a/66807155) has accurate comments and C equivalents that will actually compile. It's the same asm, but with correct comments it even in the question, so not exactly a duplicate. – Peter Cordes Dec 09 '21 at 07:50
1

Actually you are using A[1] twice as shown:

  • 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 code: f = &A[0] + A[1]

  • 1
    Yes, and `A[1]` holds a copy of `&A[0]`. See [How to understand this basic Assembly Code that seems to be adding two pointers?](https://stackoverflow.com/q/63891264) – Peter Cordes Dec 09 '21 at 07:55
-1

Guess this is correct.

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