2D Array in MIPS

后端 未结 2 1055
温柔的废话
温柔的废话 2020-12-17 06:16

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 t

相关标签:
2条回答
  • 2020-12-17 06:34

    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

    0 讨论(0)
  • 2020-12-17 06:44

    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:
    
    0 讨论(0)
提交回复
热议问题