Search code examples
arraysassemblyy86

Multidimensional Array (2x2) Initialization in Assembly Language - Y86


I am new to assembly language and I'm using a simpler version called Y86, essentially the same thing. I wonder how to initialize a multidimensional array in such a format, specifically making a 2x2. Later with the 2x2 I will be adding two matrices (or arrays in this case). Thank you!


Solution

  • In machine code you have available (for information storage) CPU registers and memory.

    Registers have fixed names and types and they are used like that, for example in x86 you can do mov eax, 0x12345678 to load 32b value into register eax.

    Memory is like continuous block of byte-cells, each having it's own unique physical address (like: 0, 1, 2, ... mem_size-1). So it is like 1 dimensional byte array.

    Whatever different type you want, in the end it is somehow mapped to this 1D byte array, so you have to first design how that mapping happens.

    Some mappings like for example 32 bit integers have native mappings/support in the instructions, so you can for example read whole 32b int by single instruction like mov eax,[address], not having to compose it from individual bytes, but the CPU will for you read four bytes from memory at addresses: address+0, address+1, address+2 and address+3 and concatenate it into 32 bit value (on x86 CPU in little-endian order, so the byte from address+0 is in the lowest 8 bits of final value).

    Other mappings like "array 2x2" don't have native support, and you have to design the memory layout and write the code accordingly to support it. For 2 dimensional arrays often mapping memory_offset = (row * columns_max + column) * single_element_byte_size is used.

    Like for 16x16 matrix of 32 bit floats you can calculate memory offset (from the start of matrix data, which is at offset 0):

        ; eax = column 0..15 (x), ebx = row 0..15 (y), ecx = address of matrix
        shl    ebx, 4    ; y *= 16
        add    eax, ebx  ; index = y * 16 + x
        mov    edx, [ecx + eax*4]   ; read 32 bit element from matrix[y][x]
    

    But you are of course free to devise and implement any kind of mapping you wish...


    edit: as Peter Cordes notes, some mappings favour certain task, like for example continuously designed matrices like the one above, in the task of adding two matrices, can be dealt with in the implementation as one dimensional 256 (16x16) element array, because there's no significance of row/columns in the matrix addition, so you can just add corresponding elements of both. In multiplication you have to traverse the elements in more complex patterns, where row/columns are important, so there you have to write more complex code to respect the 2D mapping logic.


    edit 2, to actually add answer to your question:

    I wonder how to initialize a multidimensional array in such a format

    Eee... this doesn't make sense from machine point of view. You simply need somewhere in memory reserved space, which represents data of the array, and you may want to set those to certain initial values, by simply writing those values into memory (by ordinary memory store instructions, like mov [ebx],eax), or for example in simple code adding two matrices of fixed values, you can define both of them directly in .data segment with some directive defining values, like for example in NASM assembler (for the simple mapping as described above):

    ; 2x2 32bit integer matrix:
    ; (14 32)
    ; (-3  4)
    matrix1:
        dd  14, 32, -3, 4
    

    (check your assembler documentation to see which directives are available to reserve+initialize part of memory)

    Which kind of memory area you want to reserve for the data (the load-time initialized .data, or stack, or dynamically allocated from OS "heap", ...), and how you load it with initial data, is up to you, but in no way related to the "two dimensional array", usually the allocation/initialization code often works with all the types as "continuous block of bytes", without caring about the inner structure of the data, that's left for the other functions, which are dealing with particular elements of the data.