我是汇编语言的新手,我使用的是一个更简单的版本,叫做 Y86,本质上是一样的。我想知道如何以这种格式初始化多维数组,特别是制作一个 2x2。稍后使用 2x2 我将添加两个矩阵(或本例中的数组)。谢谢!
1 回答
在机器代码中,您有可用的(用于信息存储)CPU 寄存器和内存。
寄存器具有固定的名称和类型,它们的使用方式类似,例如在 x86 中,您可以mov eax, 0x12345678
将 32b 值加载到寄存器eax
中。
内存就像连续的字节单元块,每个单元都有自己唯一的物理地址(如:0、1、2、... mem_size-1)。所以它就像一维字节数组。
无论你想要什么不同的类型,最终它都会以某种方式映射到这个一维字节数组,所以你必须首先设计映射是如何发生的。
某些映射(例如 32 位整数)在指令中具有本机映射/支持,因此您可以通过单个指令读取整个 32b int,mov eax,[address]
例如内存地址:address+0
,address+1
和address+2
并将address+3
其连接成 32 位值(在 x86 CPU 上以 little-endian 顺序,因此来自的字节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) 元素数组处理,因为矩阵加法中的行/列没有意义,因此您只需添加两者的相应元素即可。在乘法中,您必须以更复杂的模式遍历元素,其中行/列很重要,因此您必须编写更复杂的代码来尊重 2D 映射逻辑。
编辑 2,实际添加您的问题的答案:
我想知道如何以这种格式初始化多维数组
Eee ...从机器的角度来看,这没有意义。您只需要内存保留空间中的某个位置,它表示数组的数据,并且您可能希望将这些值设置为某些初始值,只需将这些值写入内存(通过普通的内存存储指令,如mov [ebx],eax
),或者例如简单添加两个固定值矩阵的代码,您可以使用一些指令定义值直接在.data
段中定义它们,例如在 NASM 汇编器中(对于如上所述的简单映射):
; 2x2 32bit integer matrix:
; (14 32)
; (-3 4)
matrix1:
dd 14, 32, -3, 4
(检查您的汇编器文档以查看哪些指令可用于保留+初始化部分内存)
您要为数据保留哪种类型的内存区域(加载时初始化.data
,或堆栈,或从操作系统“堆”动态分配,...),以及如何使用初始数据加载它,取决于您,但与“二维数组”无关,通常分配/初始化代码通常与所有类型一起作为“连续字节块”工作,而不关心数据的内部结构,这留给其他函数,处理数据的特定元素。