представляют структуру в mips32 - PullRequest
0 голосов
/ 07 февраля 2020

Я изучаю Mips32 для экзамена, и недавно я бродил, как перевести структуру c в mips. Я довольно плохо знаком с MIPS и ассемблерным кодом в целом, но я попытался собрать все свои знания, чтобы выработать решение.

Допустим, у меня есть простая C структура:

struct Student
{
    int id;
};

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

Я хочу сохранить все данные в стеке, например:

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

, и если у меня несколько учеников, я просто создаю подпрограмму, в которой аргументы хранятся в стек. Хотя у меня есть проблема, как я могу отслеживать всех студентов? может быть, с указателем кадра?

Я не знаю, является ли это подходящим способом представления структуры в mips, дайте мне знать, если есть лучшие решения.

Ответы [ 3 ]

2 голосов
/ 07 февраля 2020

У меня проблема, как я могу отслеживать всех студентов? может быть, с указателем кадра?

Вам не нужен указатель кадра, чтобы отслеживать всех студентов. Кроме того, проблема отслеживания их не уникальна для их структуры - у вас будет та же проблема отслеживания многих целых чисел. И, кроме того, проблема отслеживания многих элементов также не уникальна для сборки.

Вам нужна либо отдельная переменная для каждого элемента (часто непрактичная, особенно если количество элементов является переменным), или, структура данных: коллекция некоторого вида, например, массив или связанный список, например.


С отдельными локальными переменными в C каждая нуждается в различном имени, и в сборке у каждого будет свое смещение / местоположение в кадре стека. Пространство стека для всех будет выделено в одной инструкции, и на них все будут ссылаться через их индивидуальное смещение от указателя стека.

При желании можно использовать указатель кадра, но с MIPS пространство стека для Кадр стека функции все выделяется в одной инструкции в прологе функции , указатель стека иначе не перемещается в теле функции - и это означает, что отдельные переменные остаются с постоянными смещениями от указателя стека.


Указатель кадра может быть полезен, если:

  • машина плохо выполняет относительные смещения стека, но легко смещает относительные смещения указателя кадра, или,
  • машина требует частых нажатий и выталкиваний, которые перемещают указатель стека, что изменяет смещения, необходимые для доступа к тем же местоположениям в кадре стека - указатель кадра остается постоянным независимо от нажатия и выталкивания. (Нажатие и извлечение могут использоваться для передачи аргументов и / или временного хранения, если недостаточно регистров ЦП, например, во время вычисления выражения.)
  • Функция динамически распределяет пространство стека, например, с помощью C 's alloca.

Вообще говоря, первые два не относятся к MIPS, поэтому функциям обычно не требуется указатель кадра.


Кроме того, вы можете использовать структуру данных, например, массив, чтобы отслеживать множество элементов. На сам массив должна ссылаться переменная (в C, имя и в сборке смещение) - но, по крайней мере, есть только одна переменная, независимо от того, сколько элементов нужно отслеживать. И тогда вы переходите к индексации для доступа к отдельным элементам. (Индексирование включает в себя вычисление адреса элементов и зависит от размера элементов, но в остальном работает одинаково для массива int и массива struct.)

0 голосов
/ 07 февраля 2020

Хорошей идеей здесь было бы выделить некоторое пространство с помощью .space, затем выровнять его с помощью директивы .align n (будьте осторожны, MIPS требуется выравнивание слов), а затем просто загрузить адрес этой области памяти в свой «main»: ».

Предположим, что вы хотели бы выделить место для 10 учеников:

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
0 голосов
/ 07 февраля 2020

Ваши данные могут быть локальными, статическими c или динамически размещаться. Нет единого правила. См .: 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();
    }
}
...