二维数组和锯齿状数组的MIPS汇编

MIPS Assembly for two-dimensional array and jagged array

我看过一些从 C 代码到 MIPS 汇编代码的简单转换,并使用了一些基本指令。但是我们应该如何将以下具有jagged arraytwo-dimensional array的C代码转换为汇编代码?

int[][] A;
int[,] B;
A[B[0, 1]][A[1][2]] + B[B[j, 1], i]

我在互联网上搜索过,但不幸的是,我找不到好的资源或教程。我知道我们应该如何使用 one-dimensional array 并根据基地址找到内存地址并使用偏移量。但是我不知道如何解决这个问题并将其MIPS代码写在纸上。我将不胜感激。

这些不是 C 代码,这看起来像 C#。

int[][] A; // C# declaration for jagged multidimensional array
int[,] B;  // C# declaration for rectangular multidimensional array

首先,让我们看一下更简单、更规则的矩形数组。

矩形多维数组的 C 代码为:

int B[5][10];  // C declaration for rectangular array

此片段共请求 50 个整数元素,结构为 5 行,其中行大小为 10 个元素。

由于逻辑数据结构是二维的,而物理内存只是一维的,我们必须将二维结构映射到一维。有两种方法,一种是row-major and the other column-major。如果我们认为索引有 5 是行,10 是列,那么我们可以说 C 语言使用 row-major 排序。

(映射数组有两种选择类似于 multi-byte(即单词)项中各个字节有两种合理排序的想法:大端和小端。)

数组在某种意义上是立即数:这个结构中没有存储指针或引用,只有 50 个整数元素。

通过地址计算访问元素:

B[r][c]中我们计算addr = B + (r * 10 + c) * 4,其中10代表行的大小,4是一个整数元素的大小。乘法就是所谓的缩放。因为每行引用 10 个元素,所以第 1 行开始比第 0 行向下 10 个位置。因为每个元素占用 4 个字节,并且这 4 个字节中的每一个都占用一个内存地址,所以第 1 列从第 0 列向下 4 个字节开始。综上,元素0,0B + (0*10+0)*4,与B是同一个地址值,元素1,2B + (1*10+2)*4,也就是[=21] =] — 第二行的第三个元素 (+8) (+10*4).

可以取消引用 addr 以从数组中加载 r,c 元素,或将更新后的值存储在 r,c

(如果我们选择 column-major 排序,则公式将为 addr = B + (c * 5 + r) * 4。如果列索引变化更快,即如果我们使用 for ( r = .. ) for ( c = .. ) { },则行主要排序更好,而对于 column-major 我们更喜欢相反的情况,更快地改变行索引——内循环的索引比外循环的索引变化更快。它们之间的区别与缓存利用率有关(没有缓存没关系。)


锯齿状数组是数组的数组。涉及的每个数组都是 one-dimensional,因此虽然每个单独的数组仍然是矩形,但矩形不适用于整个“2D”数组的二维结构。

在 C 中,交错数组被声明为指针数组,其中指针本身是对零个或多个整数元素(或为空)的单个数组的引用。

int *A[10];

这里声明了一个数组([]优先于*,所以这里取int *(A[10]),每个数组元素的类型都是指向int的指针。

这个数组的总存储大小是40字节,10 * 指针大小,4,在MIPS 32位系统上。数组的每个元素都是指针类型。此数组声明没有保留任何整数!有 10 个指向整数(数组)的指针的位置,每个位置的 10 个中的每一个都必须通过初始化程序或分配进一步指定。因为这个数组的元素是指向整数的指针,所以每个这样的指针都可以为空或引用不同数量的整数的存储。如果你想知道每个(行)有多少个整数had/has,你将不得不单独存储该信息,因为没有内置机制来存储这个声明。

总而言之,C 中的锯齿状数组存在以下问题:

  • 此声明仅分配指针数组(指针数组)的存储空间。
  • 存储(指针元素)将被初始化为零,对于全局声明,以及在使用 calloc 时,但使用 malloc 或作为局部变量声明时,这些指针将未初始化(即垃圾)。
  • 即使我们用存储填充单个指针,也没有固有记录每个元素位置引用的存储长度(多少个整数的计数)。该数组可以是锯齿状的,但您必须以其他方式记住该形状(即在其他数据结构中,例如与指针数组具有相同元素计数的简单整数数组。)

访问交错数组的元素意味着从第一个数组获取指针元素,并使用它来计算整数元素的地址。这两个操作都涉及 one-dimensional 数组,因此至少在这个意义上,概念上更简单:不存在行与列主要排序的问题。

一个元素的地址,A[r][c] 计算如下:

addr = (*(A + r * sizeof(pointer))) + c * sizeof(int)

其中第一个 * 是间接获取索引 r 处的指针。这个addr可以和上面矩形数组addr后面的描述一样使用


MIPS 实现然后,其中任何一个都相当简单。全局存储,预留适量。在代码中,计算元素地址并在计算出 addr.

后使用 lwsw