簡體   English   中英

表示 mips32 中的結構

[英]represent a struct in mips32

我正在為考試學習 Mips32,最近我在徘徊如何在 mips 中翻譯 ac 結構。 總的來說,我對 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 中表示結構的合適方法,如果有更好的解決方案,請告訴我。

但是我有一個問題,我如何跟蹤所有學生? 也許帶有幀指針?

您不需要幀指針來跟蹤所有學生。 此外,跟蹤它們的問題並不是結構體所獨有的——您會遇到跟蹤許多整數的相同問題。 更進一步,跟蹤許多項目的問題也不是裝配所獨有的。

您需要的是每個項目的單獨變量(通常不切實際,尤其是項目數量可變的情況下),或者是數據結構:某種類型的集合,例如數組或鏈表。


在 C 中使用單獨的局部變量時,每個變量都需要不同的名稱,並且在匯編中每個變量在堆棧幀中都有不同的偏移量/位置。 所有的堆棧空間都將在一條指令中分配,並且它們都通過它們與堆棧指針的單獨偏移量來引用。

如果您願意,可以使用幀指針,但由於使用 MIPS,函數堆棧幀的堆棧空間全部在函數序言中的一條指令中分配,堆棧指針不會在函數主體期間移動 - 這意味着單個變量與堆棧指針保持恆定的偏移量。


在以下情況下,幀指針可能會有所幫助:

  • 機器不能很好地堆棧相對偏移量,但可以輕松地進行幀指針相對偏移量,或者,
  • 機器需要頻繁的推送和彈出來移動堆棧指針,這會改變訪問堆棧幀中相同位置所需的偏移量——無論推送和彈出,幀指針都保持不變。 (如果 CPU 寄存器不足,例如在表達式求值期間,推入和彈出可用於參數傳遞和/或臨時存儲。)
  • 函數動態分配堆棧空間,例如通過 C 的alloca

從廣義上講,前兩個不適用於 MIPS,因此函數通常不需要幀指針。


或者,您可以使用像數組這樣的數據結構來跟蹤許多項目。 數組本身需要由一個變量引用(在 C 中是一個名稱,在匯編中是一個偏移量)——但至少只有一個變量,無論要跟蹤多少項。 然后您就可以索引以訪問各個元素。 (索引涉及計算元素的地址,並取決於元素的大小,但對於 int 數組與 struct 數組的其他操作相同。)

您的數據可以是本地的、靜態的或動態分配的。 沒有一個規則。 見: 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();
    }
}

這里的一個好主意是用 .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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM