Матрицы, которые являются смежными в памяти (например, C 2D-массивы), эквивалентны 1D-массивам, просто rows * cols
элементов в строке в памяти, независимо от того, какой синтаксис asm вы используете для их размещения там. Единственное, что делает их двумерной матрицей, это то, как вы их индексируете, например,
flat_index row * width + col
.
(И для цикла по нему вы, конечно, можете сделать row_offset += width
; это add ebx, 3
в вашем матричном коде 2x3 байта.)
При добавлении матриц для каждого элемента вообще не нужно заботиться об их размерах, это та же проблема, что и при добавлении массива для каждого элемента . Так что просто зациклите индекс или указатель на каждый массив и добавьте.
Тогда вам не нужны два отдельных индекса для строки и столбца, которые просто усложнят ваш код, или (для таких небольших измерений) почти стоит развернуть, как вы делали во второй раз.
(Или, если ваш процессор поддерживает SSE2, вы можете сделать это 4 dwords за раз с paddd
.)
Это не особенное:
A db 1,2,3
db 4,5,6
Объявление таким образом с двумя отдельными db
строками для отдельных строк эквивалентно одному длинному массиву. Для MASM это может изменить SIZEOF A
(вы, вероятно, получите только первую строку, которая на самом деле находится на той же строке, что и метка A
), но больше ничего не изменится.
Причина, по которой код, который идет с ним, не будет работать для вашего случая, заключается в том, что он использует байтовые элементы и имеет другой размер матрицы (9 элементов вместо 6). Ничего общего с тем, как объявлено.
Вы могли бы полностью развернуть цикл и выполнить несколько сложных операций перемещения и добавления целочисленных регистров, если хотите, но в этом нет никакого смысла.
A[ebx][esi]
неверный синтаксис в большинстве (?) Ассемблеров. Если он собирается, я предполагаю, что это означает
A[ebx + esi]
. Это был бы нормальный способ написать это.
Он не выполняет матричную индексацию для вас, поэтому вам все еще нужно использовать смещения байтов для перехода к следующей строке.
Вы можете использовать такие вещи, как A[ebx*4 + esi]
, если число столбцов является постоянной величиной времени сборки 2 (в частности, 1, 2, 4 или 8; режимы адресации x86 имеют 2-битный счетчик сдвига для индекса) .
Обычно в asm-синтаксисе вы пишете [base + index*scale]
, но ассемблерам Intel-синтаксиса на самом деле все равно, в каком порядке появляются компоненты режима адресации. Так что, если вам нравится думать в C, где левый индекс проходит по целому строк для выбора столбца, а затем запись его в виде [A + ebx*4 + esi]
имеет смысл, если у вас была матрица uint8_t [2][4]
, поэтому шаг от элемента к следующей строке вниз равен 4.
Для элемента dword (как в вашем первом примере) вместо байтовых элементов (например, вашего 2-го) вам нужно масштабировать свои индексы или уже на 4 (например, A[ebx*4]
или сделать их смещение байтов с помощью add esi, 4
вместо inc esi
.