我已經看到了從 C 代碼到 MIPS 匯編代碼的一些簡單轉換,并使用了一些基本指令。但是我們應該如何將下面的具有jagged arrayand的 C 代碼轉換two-dimensional array為匯編呢?
int[][] A;
int[,] B;
A[B[0, 1]][A[1][2]] B[B[j, 1], i]
我在互聯網上搜索過,但不幸的是,我找不到好的來源或教程。我知道我們應該如何使用 aone-dimensional array并根據基地址找到記憶體地址并使用偏移量。但我不知道如何解決這個問題,只在紙上寫它的 MIPS 代碼。我將不勝感激任何幫助。
uj5u.com熱心網友回復:
這些不是 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 ,另一種是 column-major。如果我們認為具有 5 的索引是行和 10 的列,那么我們可以說 C 語言使用行優先排序。
(映射陣列有兩種選擇類似于多位元組(即字)項中的單個位元組有兩種合理的排序:大端和小端。)
陣列在某種意義上是直接的:這個結構中沒有存盤指標或參考,只有 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,即B 48— 第 2 行 ( 10*4) 的第 3 個元素 ( 8)。
addr可以取消參考以從陣列中加載元素,r,c或將更新的值存盤在r,c.
(如果我們選擇以列為主的排序,那么公式將addr = B (c * 5 r) * 4是for ( r = .. ) for ( c = .. ) { }— 內部回圈的索引比外部回圈的索引變化得更快。它們之間的差異與快取利用率有關(沒有快取,這無關緊要)。)
鋸齒狀陣列是陣列的陣列。所涉及的每個陣列都是一維的,因此雖然每個單獨的陣列仍然存在矩形形狀,但矩形形狀不適用于整個“2D”陣列的二維結構。
在 C 中,鋸齒狀陣列被宣告為指標陣列,其中指標本身是對零個或多個整數元素(或為空)的單個陣列的參考。
int *A[10];
這宣告了一個陣列([] 優先于 *,所以這被視為int *(A[10]),每個陣列元素的型別都是指向 int 的指標。
The total storage size of this array is 40 bytes, 10 * size of pointer, 4, on MIPS 32-bit system. Each element of the array is a pointer type. There are no integers reserved by this array declaration! There are positions for 10 pointers to integer (arrays), and each of 10 for each position must be further specified, by an initializer or by allocation. Because the elements of this array are pointers to integer, each such pointer can be null or refer to storage of a different number of integers. If you wanted to know how many integers each one (row) had/has, you will have to store that information separately, because there is no built in mechanism to store that with this declaration.
In summary, jagged arrays in C have the following issues:
- Only storage for the pointer array (array of pointer) is allocated by this declaration.
- The storage (the pointer elements) will be initialized to zero, for a global declaration, and also when using
calloc, but usingmallocor as a local variable declaration, those pointers will be uninitialized (i.e. garbage). - Even when we populate the individual pointers with storage, there is no inherent recording of the length of the storage (the count of how many integer) are referred to by each element position. The array can be jagged, but you would have to remember that shape in some other way (i.e. in other data structure, like a simple array of integer of the same element count as the pointer array.)
Accessing an element of a jagged array means obtaining the pointer element from the first array, and using that to compute the address of an integer element. Both of these operations involve one-dimensional arrays, so in at least that sense, is conceptually simpler: there is no issue of row vs. column major ordering.
An element's address, A[r][c] is computed as follows:
addr = (*(A r * sizeof(pointer))) c * sizeof(int)
where the first * is indirection that fetches the pointer at index r. This addr can be used the same as in the description after addr for rectangular array above.
The MIPS implementation of either of these is then fairly straightforward. For global storage, reserve the appropriate amount. In code, compute element addresses and use lw or sw once you've computed an addr.
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/456438.html
