汇编语言中的多维数组 (2x2) 初始化 - Y86

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

我是汇编语言的新手,我使用的是称为 Y86 的更简单版本,本质上是一样的。我想知道如何以这种格式初始化多维数组,特别是制作一个 2x2.稍后我将使用 2x2 添加两个矩阵(在本例中为数组)。谢谢!

在机器代码中,您有可用的(用于信息存储)CPU 个寄存器和内存。

寄存器有固定的名称和类型,它们就是这样使用的,例如在 x86 中,您可以 mov eax, 0x12345678 将 32b 值加载到寄存器 eax.

内存就像连续的字节单元块,每个单元格都有自己唯一的物理地址(例如:0、1、2,... mem_size-1)。所以它就像一维字节数组。

无论你想要什么不同的类型,最终它都会以某种方式映射到这个一维字节数组,所以你必须首先设计映射是如何发生的。

一些映射,例如 32 位整数,在指令中具有原生 mappings/support,因此您可以通过 mov eax,[address] 等单个指令读取整个 32b int,而不必从单独的指令中进行组合字节,但是 CPU 将为您从内存中的地址读取四个字节:address+0address+1address+2address+3 并将其连接成 32 位值(在 x86 CPU 上以小端顺序排列,因此来自 address+0 的字节位于最终值的最低 8 位)。

其他映射如"array 2x2"没有原生支持,你必须设计内存布局并相应地编写代码来支持它。对于二维数组,通常使用映射 memory_offset = (row * columns_max + column) * single_element_byte_size

与 32 位浮点数的 16x16 矩阵一样,您可以计算内存偏移量(从矩阵数据的开始,偏移量为 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]

但是您当然可以自由设计和实施您希望的任何类型的映射...


编辑:正如 Peter Cordes 所指出的,一些映射有利于某些任务,例如像上面那样连续设计的矩阵,在添加两个矩阵的任务中,可以在实现中作为一维 256 (16x16 ) 元素数组,因为row/columns在矩阵加法中没有意义,所以只需要将两者的对应元素相加即可。在乘法中,您必须以更复杂的模式遍历元素,其中 row/columns 很重要,因此您必须编写更复杂的代码以遵守 2D 映射逻辑。


编辑 2,实际为您的问题添加答案:

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

Eee...从机器的角度来看这没有意义。您只需要在内存中的某个地方保留 space,它代表数组的数据,并且您可能希望将这些值设置为某些初始值,只需将这些值写入内存(通过普通的内存存储指令,如 mov [ebx],eax),或者例如在简单的代码中添加两个固定值的矩阵,您可以直接在 .data 段中使用一些指令定义值来定义它们,例如在 NASM 汇编器中(对于如上所述的简单映射):

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

(检查您的汇编程序文档以查看哪些指令可用于保留+初始化部分内存)

您要为数据保留哪种内存区域(加载时初始化.data,或堆栈,或从OS"heap"动态分配,... ),以及如何用初始数据加载它,取决于您,但与 "two dimensional array" 没有任何关系,通常 allocation/initialization 代码通常适用于所有类型,如 "continuous block of bytes",在不关心数据的内部结构的情况下,留给处理数据的特定元素的其他函数。