PurpleKiwi
PurpleKiwi

Reputation: 90

represent a struct in mips32

I'm studying Mips32 for an exam and recently I was wandering how to translate a c struct in mips. I'm fairly new to mips and assembly code in general, but I have tried to gather all my knowladge to work out a solution.

Let's say I have a simple C struct:

struct Student
{
    int id;
};

int main()
{
    struct Student student;
    student={111111};
    return 0;
}

What I have in mind is to store all data in the stack, like that:

sub $sp,$sp,4
li  $t1,111111
sw  $t1,($sp)

and if I have more than one student, I simply create a routine that stores the arguments in the stack. I have a problem though, how can I keep track of all the students? maybe with a frame pointer ?

I don't know if that is the appropriate way to represent a struct in mips, let me know if there are better solutions.

Upvotes: 0

Views: 2309

Answers (3)

apfel
apfel

Reputation: 101

A good idea here would be to allocate some space with the .space , then align it via the .align n directive (be cautious MIPS needs word alignment) and then just load the address of this memory area in your "main:".

Let's assume that you would like to allocate space for 10 Students:

std_struct: .align 2
           .space 40   # 10students, 1 word=4 bytes each
.text

main:

la $s0, std_struct #now everything should be parsable via $s0 register

Upvotes: 0

Erik Eidt
Erik Eidt

Reputation: 26656

I have a problem though, how can I keep track of all the students? maybe with a frame pointer ?

You don't need a frame pointer to keep track of all the students.  Further, the problem of keeping track of them is not unique to their being struct's — you would have the same problem keeping track of many of integers.  And further still, the problem of keeping track of many items is also not unique to assembly.

What you need is either a separate variable for each item (often impractical, especially if the number of items is variable), or, a data structure: a collection of some sort, e.g. an array or linked list, for example.


With a separate local variables in C each needs a different name, and, in assembly each would have a different offset/location in the stack frame.  Stack space for all would be allocated in one instruction, and they all be referenced via their individual offset from the stack pointer.

A frame pointer can be used if you like, but since with MIPS the stack space for a function's stack frame is all allocated in one instruction in function prologue, the stack pointer doesn't otherwise move during the function's body — and that means that the individual variables remain at constant offsets from the stack pointer.


A frame pointer can be helpful if either:

  • the machine doesn't do stack relative offsets well, but does frame pointer relative offsets easily, or,
  • the machine requires frequent pushing and popping that move the stack pointer, which changes the offsets needed to access the same locations in the stack frame — a frame pointer remains constant regardless of pushing and popping.  (Pushing and popping may be used for argument passing, and/or temporary storage if there are insufficient CPU registers, e.g. during expression evaluation.)
  • A function dynamically allocate stack space, e.g. via C's alloca.

Broadly speaking, the first two do not apply to MIPS, so functions generally don't need a frame pointer.


Alternatively, you can use a data structure like an array to keep track of many items.  The array itself needs to be referred to by a variable (in C, a name, and in assembly an offset) — but at least there's only one variable regardless of how many items to keep track of.  And then you're down to indexing to access the individual elements.  (Indexing involves computing the address of the elements, and depends on the size of the elements, but otherwise operates the same for an int array vs. a struct array.)

Upvotes: 2

0___________
0___________

Reputation: 67546

your data can be local, static or dynamically allocated. There is no one rule. See: https://godbolt.org/z/gfDVD8

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

typedef struct
{
    int x;
    int y[4];
    char name[23];
}MYSTRUCT_t;



MYSTRUCT_t my_global_struct[10];

void my_global_struct_foo(void)
{
    for(size_t pos = 0; pos < 10; pos++)
    {
        my_global_struct[pos].x = rand();
        my_global_struct[pos].y[0] = my_global_struct[pos].x / 2;
        my_global_struct[pos].name[4] = my_global_struct[pos].y[0];
    }
}

void my_static_struct_foo(void)
{
    static MYSTRUCT_t my_static_struct[10];

    for(size_t pos = 0; pos < 10; pos++)
    {
        my_static_struct[pos].x = rand();
        my_static_struct[pos].y[0] = my_static_struct[pos].x / 2;
        my_static_struct[pos].name[4] = my_static_struct[pos].y[0];
    }
}

void my_local_struct_foo(void)
{
    volatile MYSTRUCT_t my_local_struct[10];

    for(size_t pos = 0; pos < 10; pos++)
    {
        my_local_struct[pos].x = rand();
        my_local_struct[pos].y[0] = rand();
        my_local_struct[pos].name[4] = rand();
    }
}

Upvotes: 0

Related Questions