Инициализация многомерного массива (2x2) на языке ассемблера - Y86

Я новичок в ассемблере, и я использую более простую версию под названием Y86, по сути, то же самое. Интересно, как инициализировать многомерный массив в таком формате, конкретно сделав 2х2. Позже с 2x2 я буду добавлять две матрицы (или массивы в этом случае). Спасибо!

1 ответ

Решение

В машинном коде у вас имеются (для хранения информации) регистры процессора и память.

Регистры имеют фиксированные имена и типы, и они используются таким образом, например, в x86 вы можете сделать mov eax, 0x12345678 загрузить значение 32b в регистр eax,

Память подобна непрерывному блоку байтовых ячеек, каждая из которых имеет свой уникальный физический адрес (например, 0, 1, 2, ... mem_size-1). Так что это как одномерный массив байтов.

Какой бы тип вы ни выбрали, в конце концов, он каким-то образом сопоставляется с этим 1D-байтовым массивом, поэтому вы должны сначала спроектировать, как происходит это отображение.

Некоторые отображения, такие как, например, 32-битные целые числа, имеют в инструкциях собственные отображения / поддержку, поэтому вы можете, например, прочитать целое 32b int с помощью одной инструкции, например mov eax,[address]Не нужно составлять его из отдельных байтов, но процессор будет для вас читать четыре байта из памяти по адресам: address+0, address+1, address+2 а также address+3 и объединить его в 32-битное значение (на процессоре x86 в порядке с прямым порядком байтов, поэтому байт от address+0 находится в младших 8 битах конечного значения).

Другие отображения, такие как "массив 2x2", не имеют встроенной поддержки, и вам необходимо спроектировать макет памяти и написать соответствующий код для его поддержки. Для двумерных массивов часто отображается memory_offset = (row * columns_max + column) * single_element_byte_size используется.

Как и для матрицы 16x16 с 32-разрядными числами с плавающей запятой, вы можете рассчитать смещение памяти (от начала данных матрицы, которое находится со смещением 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]

Но вы, конечно, можете разрабатывать и реализовывать любые виды карт по вашему желанию...


редактировать: как отмечает Питер Кордес, некоторые сопоставления благоприятствуют определенной задаче, например, например, непрерывно спроектированные матрицы, подобные приведенной выше, в задаче добавления двух матриц могут рассматриваться в реализации как одномерный массив элементов размером 256 (16x16), поскольку нет никакого значения строки / столбца в добавлении матрицы, так что вы можете просто добавить соответствующие элементы обоих. При умножении вы должны обходить элементы в более сложных шаблонах, где важны строки / столбцы, поэтому вы должны написать более сложный код, чтобы соответствовать логике 2D-отображения.


отредактируйте 2, чтобы добавить ответ на свой вопрос:

Интересно, как инициализировать многомерный массив в таком формате

Э-э-э... это не имеет смысла с точки зрения машины. Вам просто нужно где-то в зарезервированном пространстве памяти, которое представляет данные массива, и вы можете установить для них определенные начальные значения, просто записав эти значения в память (обычными инструкциями хранения памяти, такими как mov [ebx],eax), или, например, в простом коде, добавляющем две матрицы фиксированных значений, вы можете определить их оба непосредственно в .data сегмент с некоторыми директивами, определяющими значения, как, например, в ассемблере NASM (для простого отображения, как описано выше):

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

(проверьте документацию на ассемблере, чтобы узнать, какие директивы доступны для резервирования + инициализации части памяти)

Какой тип области памяти вы хотите зарезервировать для данных (время загрузки инициализировано .dataили стек, или динамическое выделение из "кучи" ОС, ...), и то, как вы загружаете его с исходными данными, зависит от вас, но никак не связано с "двумерным массивом", обычно это распределение / инициализация код часто работает со всеми типами как "непрерывный блок байтов", не заботясь о внутренней структуре данных, оставленной для других функций, которые имеют дело с определенными элементами данных.

Другие вопросы по тегам