Как удалить элемент массива в сборке 68k

У меня есть массив структур, и мне нужно удалить элемент в заданной позиции. Вот смещения для моей структуры.

MOVIE       equ  62
title       equ  0
year        equ  52
time        equ  54
rating      equ  56

Предполагая, что у меня есть массив из 12 элементов, как мне удалить элемент в позиции 5?


person awave    schedule 20.11.2017    source источник
comment
Копируя все, что над ним, на один слот вниз.   -  person 500 - Internal Server Error    schedule 20.11.2017
comment
В качестве альтернативы, если вам не важен порядок, просто скопируйте туда последний элемент.   -  person Jester    schedule 20.11.2017
comment
Для метода копирования всего вниз теперь у вас та же проблема, что и для memmove, поэтому используйте оптимизированную реализацию memmove. Или используйте уровень косвенности, который позволяет вам просто удалить из массива указателей.   -  person Peter Cordes    schedule 21.11.2017
comment
@ 500-InternalServerError Спасибо, помогло!   -  person awave    schedule 21.11.2017
comment
rating составляет шесть байтов, или я неправильно интерпретирую первую строку?   -  person unwind    schedule 15.12.2017
comment
@unwind это была строка из 5 символов (6 включая нулевой терминатор). должен был сделать это немного более ясным   -  person awave    schedule 17.12.2017


Ответы (1)


Во-первых, у вас не будет «массива структур». Идеальная форма — иметь массив указателей на структуры, где каждый указатель ссылается на свою собственную структуру.

         MOVEQ   #5,D0       ;element you want to delete
         BSR     DEL_MOVE
         SIMHALT

DEL_MOVE
         LSL.W   #2,D0        ; long words
         LEA     MOVIES,A0    ; array start
         LEA     0(A0,D0),A2  ; element in array (starts at 0)
         LEA     11*4(A0),A1  ; end of array -1
DEL      MOVE.L  4(A2),(A2)+  ; move down
         CMP.L   A2,A1        ; at end yet?
         BLT.S   DEL          ; branch if not
         MOVE.L  #0,(A2)+     ; last element is null
         RTS


MOVIES   DC.L    MOVIE1, MOVIE2, MOVIE3 ...
MOVIE1   DS.B    62
MOVIE2   DS.B    62
         ...
person vogomatix    schedule 06.09.2018
comment
Ваш нынешний код будет перемещать мусор в новый верхний элемент! То есть, если длинное слово в 4(A2) не было определено как содержащее подходящее значение указателя (нулевое или другое). - person Fifoernik; 06.09.2018
comment
Извините, но это исправление записывает нуль после массива из 12 длинных слов! MOVE, которое вы написали, должно стать: MOVE.L #0,-4(A2). Это решает проблему независимо от изменения с LEA 12*4(A0),A1 на LEA 11*4(A0),A1, что на самом деле не делает ничего полезного! - person Fifoernik; 07.09.2018
comment
Проблема существует, если это последний элемент, который необходимо удалить. Операция перемещения вниз (которая в данном случае избыточна) выполняется безоговорочно, а за массивом записывается ноль. - person Fifoernik; 08.09.2018
comment
Самое простое и даже самое короткое решение — сохранить код версии 1, но определить массив с завершающим нулевым указателем. MOVIES DC.L MOVIE1, MOVIE2, MOVIE3, ... ,MOVIE12, 0. - person Fifoernik; 08.09.2018
comment
Дополнительная ловушка: поскольку регистр D0 был инициализирован и управлялся как слово, инструкция LEA 0(A0,D0),A2 не стала LEA 0(A0,D0.W),A2. Я не знаю, будет ли ваш ассемблер использовать .W по умолчанию! - person Fifoernik; 08.09.2018
comment
Если размер кода имеет какое-либо значение, инструкция MOVE.L #0,(A2)+ тратит впустую 4 байта, поскольку CLR.L (A2) выполняет работу только со своим словом кода операции. Также зачем использовать режим постинкрементной адресации в этом месте кода? - person Fifoernik; 08.09.2018
comment
Нет, он не пишет за массивом, так как я также изменил ссылку на последний элемент на 4 байта вниз. Я стараюсь избегать CLR по привычке, поскольку он не так быстр, как MOVEQ при очистке регистров, однако вы правы в этом случае. - person vogomatix; 08.09.2018