MIPS 中的二维阵列

发布于 2024-10-16 04:04:40 字数 227 浏览 3 评论 0原文

我在网上和这个网站上进行了搜索,但找不到在 MIPS 中实现 2D 数组的好例子。我希望能够看到一个示例,说明如何遍历数组以便将数据放置在特定索引处以及如何打印数组,如下所示。

例如 5x5 数组,其中 $ 是每个索引中的数据。

  a b c d e
1 $ $ $ $ $
2 $ $ $ $ $
3 $ $ $ $ $
4 $ $ $ $ $
5 $ $ $ $ $

I've searched online and on this site and I can not find a good example of implementing a 2D Array in MIPS. I would like to be able to see an example of how to go through the array in order to place data at a specific index and how to print the array out like shown below.

Such as a 5x5 array where $ would be the data in each index.

  a b c d e
1 $ $ $ $ $
2 $ $ $ $ $
3 $ $ $ $ $
4 $ $ $ $ $
5 $ $ $ $ $

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

厌味 2024-10-23 04:04:40

关于二维数组您需要了解的一切:

  1. 分配
  2. 实现嵌套循环

要分配您需要计算(#row X #column) X #byte required

有关字节数您需要 1 个字符、4 个整数、4 个单精度浮点数、8 个双精度浮点数。
例如:

要动态分配 150 个双精度元素的数组,例如 15 行和 10 列:

li  $t1,15
li  $t2,10
mul $a0, $t1, $t2
sll $a0, $a0, 3   # multiply number of elements by 2^3 = 8
                  # because each double precision floating point number takes 8 bytes
li  $v0, 9
syscall
move $s0,$v0   # save array address in $s0

要获取 索引 (3,4) 的地址:

  • 行主要:8 X (10 X 3 + 4) = 272 ,然后将其添加到基地址
  • Column Major : 8 X (15 X 4 + 3) = 504,然后将其添加到基地址

旁注:我使用逻辑左移而不是乘法因为 MIPS 中的移位 (sll) 需要 1 个时钟周期,而 mul 指令需要 33 个时钟周期。从而,提高了代码的效率。

在此处输入图像描述


更新/编辑(距离我写这篇文章已经过去 3 年多了)答案,所以我会改进我的答案):

以行主格式迭代整数(不是双精度)的二维矩阵的伪代码如下:

for (int i = 0; i < array height; i++) {
    for (int j = 0; j < array width; j++) {

        prompt and read array value

        row index = i
        column index = j

        memory[array base address + 4 * (array width * row index + column index)] = array value
    }
}

但是,迭代的伪代码列优先格式的整数(非双精度)二维矩阵如下:

for (int i = 0; i < array height; i++) {
   for (int j = 0; j < array width; j++) {

       prompt and read array value

       row index = i
       column index = j

       memory[array base address + 4 * (array height * column index + row index)] = array value
   }
}

注意:正如我们所见,循环的结构保持不变,但地址保持不变计算部分略有改变。现在实现上述伪代码很简单。我们需要 2 个嵌套循环。假设:

$t0 <-- base address of array (or matrix or 2 dimensional array)
$t1 <-- height of matrix
$t2 <-- width of matrix
i <---- row index
j <---- column index

将值读入行优先矩阵的实现:

        .data
read_row_matrix_prompt_p:   .asciiz "Enter an integer: "
###########################################################

        .text
read_row_matrix:
    li $t3, 0               # initialize outer-loop counter to 0

read_row_matrix_loop_outer:
    bge $t3, $t1, read_row_matrix_loop_outer_end

    li $t4, 0               # initialize inner-loop counter to 0

read_row_matrix_loop_inner:
    bge $t4, $t2, read_row_matrix_loop_inner_end

    mul $t5, $t3, $t2       # $t5 <-- width * i
    add $t5, $t5, $t4       # $t5 <-- width * i + j
    sll $t5, $t5, 2         # $t5 <-- 2^2 * (width * i + j)
    add $t5, $t0, $t5       # $t5 <-- base address + (2^2 * (width * i + j))

    li $v0, 4               # prompt for number
    la $a0, read_row_matrix_prompt_p
    syscall

    li $v0, 5               # read a integer number
    syscall

    sw $v0, 0($t5)          # store input number into array

    addiu $t4, $t4, 1       # increment inner-loop counter

    b read_row_matrix_loop_inner    # branch unconditionally back to beginning of the inner loop

read_row_matrix_loop_inner_end:
    addiu $t3, $t3, 1       # increment outer-loop counter

    b read_row_matrix_loop_outer    # branch unconditionally back to beginning of the outer loop

read_row_matrix_loop_outer_end:

将值读入列优先矩阵的实现:

   .data
read_col_matrix_prompt_p:   .asciiz "Enter an integer: "
###########################################################

   .text
read_col_matrix:
    li $t3, 0               # initialize outer-loop counter to 0

read_col_matrix_loop_outer:
    bge $t3, $t1, read_col_matrix_loop_outer_end

    li $t4, 0               # initialize inner-loop counter to 0

read_col_matrix_loop_inner:
    bge $t4, $t2, read_col_matrix_loop_inner_end

    mul $t5, $t4, $t1       # $t5 <-- height * j
    add $t5, $t5, $t3       # $t5 <-- height * j + i
    sll $t5, $t5, 2         # $t5 <-- 2^2 * (height * j + i)
    add $t5, $t0, $t5       # $t5 <-- base address + (2^2 * (height * j + i))

    li $v0, 4               # prompt for number
    la $a0, read_col_matrix_prompt_p
    syscall

    li $v0, 5               # read a integer number
    syscall

    sw $v0, 0($t5)          # store input number into array

    addiu $t4, $t4, 1       # increment inner-loop counter

    b read_col_matrix_loop_inner    # branch unconditionally back to beginning of the inner loop

read_col_matrix_loop_inner_end:
    addiu $t3, $t3, 1       # increment outer-loop counter

    b read_col_matrix_loop_outer    # branch unconditionally back to beginning of the outer loop

read_col_matrix_loop_outer_end:

All you need to know about 2 Dimensional arrays:

  1. Allocate
  2. Implement nested loops

To allocate you you need to calculate ( #row X #column ) X #byte needed

regarding number of bytes you need 1 for char, 4 integer, 4 single precision float, 8 for double precision float.
For example:

To dynamically allocate array of 150 double precision elements such that 15 rows and 10 column :

li  $t1,15
li  $t2,10
mul $a0, $t1, $t2
sll $a0, $a0, 3   # multiply number of elements by 2^3 = 8
                  # because each double precision floating point number takes 8 bytes
li  $v0, 9
syscall
move $s0,$v0   # save array address in $s0

To get address of index (3,4) :

  • Row major : 8 X (10 X 3 + 4) = 272 , then add it to the base address
  • Column major : 8 X (15 X 4 + 3) = 504, then add it to the base address

Side note: I used shift left logical instead of multiply because shifting (sll) in MIPS takes 1 clock cycle but mul instruction takes 33 clock cycles. Thus, improving efficiency of the code.

enter image description here


Update / Edit (it has been over 3 years past since I wrote this answer, so I will improve my answer):

The pseudo-code to iterate through 2 dimensional matrix of integers (not doubles) in row-major format is the following:

for (int i = 0; i < array height; i++) {
    for (int j = 0; j < array width; j++) {

        prompt and read array value

        row index = i
        column index = j

        memory[array base address + 4 * (array width * row index + column index)] = array value
    }
}

However, pseudo-code to iterate through 2 dimensional matrix of integers (not doubles) in column-major format is the following:

for (int i = 0; i < array height; i++) {
   for (int j = 0; j < array width; j++) {

       prompt and read array value

       row index = i
       column index = j

       memory[array base address + 4 * (array height * column index + row index)] = array value
   }
}

Note: As we can see, the structure of the loop stays the same but the address calculation part has been slightly changed. Now implementing the above pseudo-codes are straightforward. We need 2 nested loops. Assuming:

$t0 <-- base address of array (or matrix or 2 dimensional array)
$t1 <-- height of matrix
$t2 <-- width of matrix
i <---- row index
j <---- column index

Implementation of reading values into row-major matrix:

        .data
read_row_matrix_prompt_p:   .asciiz "Enter an integer: "
###########################################################

        .text
read_row_matrix:
    li $t3, 0               # initialize outer-loop counter to 0

read_row_matrix_loop_outer:
    bge $t3, $t1, read_row_matrix_loop_outer_end

    li $t4, 0               # initialize inner-loop counter to 0

read_row_matrix_loop_inner:
    bge $t4, $t2, read_row_matrix_loop_inner_end

    mul $t5, $t3, $t2       # $t5 <-- width * i
    add $t5, $t5, $t4       # $t5 <-- width * i + j
    sll $t5, $t5, 2         # $t5 <-- 2^2 * (width * i + j)
    add $t5, $t0, $t5       # $t5 <-- base address + (2^2 * (width * i + j))

    li $v0, 4               # prompt for number
    la $a0, read_row_matrix_prompt_p
    syscall

    li $v0, 5               # read a integer number
    syscall

    sw $v0, 0($t5)          # store input number into array

    addiu $t4, $t4, 1       # increment inner-loop counter

    b read_row_matrix_loop_inner    # branch unconditionally back to beginning of the inner loop

read_row_matrix_loop_inner_end:
    addiu $t3, $t3, 1       # increment outer-loop counter

    b read_row_matrix_loop_outer    # branch unconditionally back to beginning of the outer loop

read_row_matrix_loop_outer_end:

Implementation of reading values into column-major matrix:

   .data
read_col_matrix_prompt_p:   .asciiz "Enter an integer: "
###########################################################

   .text
read_col_matrix:
    li $t3, 0               # initialize outer-loop counter to 0

read_col_matrix_loop_outer:
    bge $t3, $t1, read_col_matrix_loop_outer_end

    li $t4, 0               # initialize inner-loop counter to 0

read_col_matrix_loop_inner:
    bge $t4, $t2, read_col_matrix_loop_inner_end

    mul $t5, $t4, $t1       # $t5 <-- height * j
    add $t5, $t5, $t3       # $t5 <-- height * j + i
    sll $t5, $t5, 2         # $t5 <-- 2^2 * (height * j + i)
    add $t5, $t0, $t5       # $t5 <-- base address + (2^2 * (height * j + i))

    li $v0, 4               # prompt for number
    la $a0, read_col_matrix_prompt_p
    syscall

    li $v0, 5               # read a integer number
    syscall

    sw $v0, 0($t5)          # store input number into array

    addiu $t4, $t4, 1       # increment inner-loop counter

    b read_col_matrix_loop_inner    # branch unconditionally back to beginning of the inner loop

read_col_matrix_loop_inner_end:
    addiu $t3, $t3, 1       # increment outer-loop counter

    b read_col_matrix_loop_outer    # branch unconditionally back to beginning of the outer loop

read_col_matrix_loop_outer_end:
我恋#小黄人 2024-10-23 04:04:40

您可以根据一维数组设置二维数组。您只需将元素从一维数组正确映射到二维数组即可。该网站有图片:

http:// www.plantation-products.com/Webster/www.artofasm.com/Windows/HTML/Arraysa2.html#1010609

您可以使用标准格式来寻址每个单元格。例如:

      a  b  c  d  e

1     0  1  2  3  4
2     5  6  7  8  9
3    10 11 12 13 14
4    15 16 17 18 19
5    20 21 22 23 24

您应该能够看到该模式:) 一般来说,如果有 M 列和 N 行,则可以在点 i * M + j - 1 处访问第 i 行、第 j 列(零索引)的单元格

You can set up a 2D array in terms of a 1D array. You just need to correctly map elements from the 1D array to the 2D array. This site has pictures:

http://www.plantation-productions.com/Webster/www.artofasm.com/Windows/HTML/Arraysa2.html#1010609

You can use a standard format for addressing each cell. For example:

      a  b  c  d  e

1     0  1  2  3  4
2     5  6  7  8  9
3    10 11 12 13 14
4    15 16 17 18 19
5    20 21 22 23 24

You should be able to see the pattern :) In general, if there are M columns and N rows, the cell at row i, column j (zero-indexed) can be accessed at point i * M + j - 1

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文