适用于二维阵列和锯齿状阵列的MIPS组件



我看到了一些从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个元素。

因为逻辑数据结构是二维的,而物理内存只有一维,所以我们必须将2D结构映射到1D上。有两种方法,一种是行专业,另一种是列专业。如果我们认为索引的5是行,10是列,那么我们可以说C语言使用行主排序。

(在映射数组时有两种选择,这类似于多字节(即单词)项中单个字节有两种合理的排序:big-endian和little-endian。)

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

通过地址计算访问元素:

B[r][c]中,我们计算addr = B + (r * 10 + c) * 4,其中10表示行的大小,4表示一个整数元素的大小。乘法就是所谓的缩放。因为每行引用10个元素,所以第1行从比第0行更靠下的10个位置开始。因为每一个元素占用4个字节,而这4个字节中的每一个都占用一个内存地址,那么第1列从比列0靠下的4个字节开始。总之,元素0,0位于B + (0*10+0)*4,与B的地址值相同,而元素1,2位于B + (1*10+2)*4,即CCD_ 11-第二行(+10*4)的第三个元素(+8)。

addr可以被解引用以从数组加载r,c元素,或者在r,c处存储更新的值。

(如果我们选择列主排序,则公式为addr = B + (c * 5 + r) * 4。如果列索引变化更快,即如果我们使用for ( r = .. ) for ( c = .. ) { },则行主排序更好,而对于列主,我们更喜欢相反的排序,即行索引变化更快——内部循环的索引变化快于外部循环的索引。它们之间的差异与缓存利用率有关(如果没有缓存,也没什么大不了的)


锯齿形阵列是阵列的阵列。所涉及的每个阵列都是一维的,因此尽管每个单独的阵列仍然有矩形形状,但矩形形状不适用于整个"阵列"的二维结构;2D";大堆

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

int *A[10];

这声明了一个数组([]优先于*,因此它被视为int *(A[10]),每个数组元素的类型都是指向int的指针。

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

总之,C中的锯齿状阵列存在以下问题:

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

访问锯齿状数组的元素意味着从第一个数组中获得指针元素,并使用它来计算整数元素的地址。这两种操作都涉及一维数组,因此至少从这个意义上讲,在概念上更简单:不存在行与列主排序的问题。

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

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

其中第一个*是取索引CCD_ 21处的指针的间接。该CCD_ 22可以与上述矩形阵列的CCD_ 23之后的描述中相同地使用。


这两种方法的MIPS实现都相当简单。对于全局存储,请保留适当的数量。在代码中,计算元素地址,并在计算出addr后使用lwsw

最新更新