Как бы вы отредактировали это так, чтобы массив сдвигался на 2 позиции? Ex. Конечный массив 30, 40,10, 20 - PullRequest
1 голос
/ 25 октября 2019

Хотите сместить массив на переменную DWORD, равную 2, чтобы конечный массив был 30,40,10,20

Хотите поддерживать массив переменной длины

.data
array DWORD 10,20,30,40
arrayType DWORD TYPE array
newArray DWORD LENGTHOF array DUP(?)
lastElement DWORD ?

.code
main PROC

;Get first element address in ESI
MOV ESI, OFFSET array

;Get address of next element in EDI
MOV EDI, OFFSET newArray
ADD EDI, TYPE newArray

;set loop count into ecx
mov ECX, LENGTHOF array

L2:
MOV EAX, [ESI]
MOV [EDI], EAX

ADD ESI, TYPE array
ADD EDI, TYPE array

LOOP L2

;set last element from array in newArray first position
MOV EDI,OFFSET newArray
MOV EAX, [ESI]
MOV [EDI], EAX

1 Ответ

0 голосов
/ 25 октября 2019

Вы пишете в отдельное место назначения, поэтому нет никаких совпадений между чтением и письмом. Это делает его довольно простым: вы выполняете цикл от первого до последнего одного массива и начинаете с середины другого массива с переносом.

например, начинаете с первого элемента места назначения и используете ветвь для условновычтите длину (в байтах) из указателя src. (Разветвление - хороший выбор по сравнению с cmov, потому что оно будет истинным только один раз; каждый раз, когда вы просто зацикливаетесь в обычном режиме.)src до конца, затем от начала до середины.

Вы можете даже использовать для этого rep movsd дважды вместо циклов, оставляя edi неизменным, чтобы продолжать добавлять пункт назначения, но сбрасывая esi вчитать с начала источника. (Если вы не собираетесь использовать векторы SIMD, rep movsd быстрее, чем цикл копирования 4 байта за раз, вероятно, для 10 элементов или более. Или с инструкцией slow-on-Intel loopточка безубыточности еще ниже.)

Для задачи фиксированного размера вы, конечно, можете просто загрузить все это в 4 регистра или использовать SSE2 movdqu -load / pshufd /movdqu - хранить, чтобы перетасовать куски меча 16-байтового вектора SIMD.


Если вам нужно было выполнить это вращение на месте (обновление одного массива вместо создания модифицированной копии), вы можете жестко закодироватьчасть «поворот на 2 позиции» по переменной длине, использующая пару чистых регистров для обработки перекрытия между записью и чтением.


Я не собираюсь публиковать код, потому что это выглядит как домашняя работа, и яне показывать пример, не просто решив его.

Но arrayType DWORD TYPE array выглядит как плохая идея. TYPE array - постоянная времени сборки;Вы не хотите хранить его в памяти и загружать как данные, просто используйте его как непосредственный, как вы делаете с ADD ESI, TYPE array

lastElement DWORD ? также не используется, и опять же, это хорошо,Используйте регистры (до тех пор, пока вы не закончите) для кусков с одним мечом в царапинах.

...