Converting C array operations to Assembly

MuffinMan1042

I am struggling trying to convert a[i+1] = a[i-1] + b[4] to assembly. Where $s0 is the address of a, $s1 is the address of b, and $s2 is the variable i. Professor mentions it can be done in 6 steps.

I have:

addi $t0, $s2, 4 #i + 1

addi $t1, $s2, -4 #i - 1

lw $t2, $t1($s0) #load a[i-1] - I know this is wrong

lw $t3, 16($s1) #load b[4]

add $t4, $t2, $t3 #add a[i-1] + b[4]

sw $t4, $t0($s0) #save to a[i+1] - I know this is wrong

The areas I know where it is wrong, I know I can't use a register for the immediate, but I am unsure how to tackle this problem otherwise. I might also be doing this completely wrong, and any help is appreciated.

Craig Estey

Here is some annotated code that I believe will work:

    .text

    .globl  main
# main -- main program
#
# a[i + 1] = a[i - 1] + b[4]
#
# arguments:
#   s0 -- address of a
#   s1 -- address of b
#   s2 -- i
#
# registers:
#   t0 -- address of a[i]
#   t1 -- value of b[4]
#   t2 -- i << 2 (i.e. a byte offset)
#   t3 -- value of a[i - 1]
#   t4 -- a[i - 1] + b[4]
main:
    sll     $t2,$s2,2               # get i << 2
    add     $t0,$s0,$t2             # get &a[i]

    lw      $t3,-4($t0)             # get a[i - 1]
    lw      $t1,16($s1)             # get b[4]

    add     $t4,$t3,$t1             # sum them
    sw      $t4,4($t0)              # a[i + 1] = sum

This is pretty close to the only sequence that can be used. The order of the lw instructions can be flipped but, otherwise, the instructions must be those shown, except for using different registers to hold different values.

For clarity, each intermediate term/step got its own t register. But, we can reduce the number of registers used if reassign/reuse registers. For example, in the first two instructions, we could replace $t2 with $t0, as we never use $t2 after that.

An optimizing compiler could/would do this. We'd end up needing only $t0-$t2 instead of $t0-$t4:

    .text

    .globl  main
# main -- main program
#
# a[i + 1] = a[i - 1] + b[4]
#
# arguments:
#   s0 -- address of a
#   s1 -- address of b
#   s2 -- i
#
# registers:
#   t0 -- i << 2
#         address of a[i]
#   t1 -- value of b[4]
#   t2 -- value of a[i - 1]
#         sum of a[i - 1] + b[4]
main:
    sll     $t0,$s2,2               # get i << 2
    add     $t0,$s0,$t0             # get &a[i]

    lw      $t2,-4($t0)             # get a[i - 1]
    lw      $t1,16($s1)             # get b[4]

    add     $t2,$t2,$t1             # sum them
    sw      $t2,4($t0)              # a[i + 1] = sum

If the code is part of a function, we could use $v0, $v1, $a0 as our temp registers as a function is permitted to use $v0-$v1 and $a0-$a3 as internal temporaries if it wishes.


UPDATE:

The comments definitely help me understand what is occurring during each instruction

Good programming style [and therefore understanding] has lots of comments. Of the right type. This is particularly important for asm because in C, a variable like number_of_users is somewhat descriptive. But, $t0 isn't.

The comments I added are what I would do for any asm code I would write for myself. And, I've been writing asm for decades.

Also, the "optimized" version has a purpose: Simplification. By freeing up $t3-$t4, they can be used to hold other things. In a more complex function, this can make the difference between a simple and easily understood one, and a needlessly complicated one that is harder understand and maintain.

For more on this, and tips on how to write asm well, based on my own experience, see my answer: MIPS linked list

the professor is not the greatest at relaying information

There is only so much that can be conveyed in a classroom setting. It can cover the basics. And, the coursework can help you learn the basics of the given language. And, IMO, professors have never been particularly good at commenting code well [enough ;-)].

When I was learning asm [on a different architecture], in addition to coursework, I was also able to work as paid programmer on a multiuser timesharing OS that was written 100% in asm. It had the same style of commenting as above.

IMO, one of the best ways to learn is analyze "expert" code. Ask the question: "Why did they do that in that way?". That's what I did and I learned a lot. I [still] give credit to that experience to this day.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Converting C code to MIPS Assembly Language

From Dev

Converting from C Loop to MIPS assembly language (bad address error)

From Dev

Converting a pointer to an array in C++ to Java (OpenCV)

From Dev

Converting byte array to unsigned long in C++

From Dev

Converting Assembly to C

From Dev

Converting a snippit of x86 Assembly Code into C

From Dev

Converting VB.Net Array to C#

From Dev

Converting a C char array to a String

From Dev

Assembly operations with inputed number

From Dev

Converting string into multidimensional char array c#

From Dev

Converting WinSCP script to C# code using WinSCP .NET assembly

From Dev

Converting into Intel 64 assembly

From Dev

Converting PHP array of arrays to C#

From Dev

Bit operations converting to an integer

From Dev

converting array of string to json object in C#

From Dev

C# Converting an int into an array of 2 bytes

From Dev

C++ Converting char to byte array

From Dev

Converting C++ function to MIPS assembly

From Dev

C Converting Char array (strings) into int array

From Dev

array from C in Assembly

From Dev

Converting array of C strings to Swift string array

From Dev

Converting JSON Array to XML in C#

From Dev

Where are the null-terminated strings when converting from C to assembly?

From Dev

Converting Assembly to C

From Dev

Converting C to mips assembly, Unaligned address error

From Dev

Assembly operations with inputed number

From Dev

Converting from c name sorting code to NASM assembly code crashes

From Dev

Converting a String Array into an Int Array in C#

From Dev

C assembly error for a given array