8085 Программа для копирования исходного блока в целевой блок с перекрывающимся адресом памяти

Опубликовано: 6 Октября, 2022

Задача состоит в том, чтобы скопировать данные из некоторого исходного блока в некоторый целевой блок при условии, что целевой блок имеет перекрывающийся адрес памяти с исходным блоком. Данные нельзя просто переместить из исходного блока в целевой, потому что целевой блок имеет перекрывающийся адрес памяти, это может привести к переопределению данных, а исходные данные могут быть потеряны без копирования в место назначения.

Перед копированием данных состояние исходного блока и блока назначения

После копирования отображается состояние целевого блока и исходного блока.

Решение:

Целью решения является копирование данных из исходного блока в другое временное место, а затем копирование данных оттуда в целевой блок. Таким образом, с помощью этого перекрывающиеся проблемы могут быть легко решены. В качестве временного местоположения можно использовать указатель стека. Сначала данные из исходного блока помещаются в стек, затем все данные извлекаются из стека и сохраняются в целевом блоке памяти.

Алгоритм:

  1. Загрузите пару HL с расположением исходного блока и инициализируйте указатель стека.
  2. Переместите длину исходного блока в регистр C и сохраните его копию в регистре B для дальнейшего использования.
  3. Увеличьте пару HL, чтобы она указывала на первый элемент исходного блока.
  4. [SAVE] Поместите элемент исходного блока, на который указывает пара HL, на вершину стека.
  5. Регистр декремента C
  6. Повторяйте [SAVE] до тех пор, пока регистр C не станет ненулевым. Другими словами, это поместит все элементы исходного блока в стек один за другим.
  7. Восстановите длину исходного блока из регистра B в регистр C.
  8. Загрузите пару HL с адресом блока назначения.
  9. [COPY] вытолкнуть элемент из стека в пару регистров DE.
  10. Переместите регистр E в адрес назначения, указанный парой HL. Другими словами, скопируйте элемент в целевой блок.
  11. Декрементный регистр С.
  12. Увеличьте пару HL, чтобы указать на следующий адрес в блоке назначения
  13. Повторяйте [COPY] до тех пор, пока регистр C не станет ненулевым. Другими словами, переместите все элементы из исходного блока в целевой блок.
  14. Остановите программу.

Программа сборки 8085

// Program begins at address 0000H
# BEGIN 0000H
// Load HL pair with source block address
    LXI H,C000H
// Initialize stack pointer
    LXI SP,B000H
// save the length of source block in register B and C
    MOV B,M
    MOV C,M
// Increment HL pair to point to first element of source block
    INX H
// Push all elements from source block onto stack
SAVE: 
    MVI D,00H
    MOV E,M
    PUSH D
    DCR C
    INX H
    JNZ SAVE
// Restore the length of source block in register C from register B
    MOV C,B
// Save destination address in DE register pair
    MOV D,M
    INX H
    MOV E,M
// To perform stable copy (that is to do not change the order of
// elements, perform copy from backward location. So, just add
// the length of block and copy element one by one and keep
// decrementing after copying each element.
    MOV A,E
    ADD C
    DCR A
    MOV E,A
// exchange the content of HL pair with DE register pair
    XCHG
// Copy elements from stack to destination location one by one
// Pop one element at a time in DE register pair and save it
// into the destination location which is currently pointed
// by the HL pair
COPY:
    POP D
// Move element from DE register pair to destination location
    MOV M,E
// decrement the counter
    DCR C
// update HL pair to next free location in destination block
// to copy another element (if any remaining)
    DCX H
    JNZ COPY
// Stop the program
    HLT

Объяснение:

ИНСТРУКЦИИ ОБЪЯСНЕНИЕ ИНСТРУКЦИЙ
# НАЧАЛО 0000Ч Программа начинается с адреса 0000H.
LXI H, C000H Загрузить пару HL с адресом исходного блока
LXI СП, B000H Инициализировать указатель стека
МОВ Б,М сохранить длину исходного блока в регистре B
МОВ С,М сохранить длину исходного блока в регистре C
ИНКС Н Увеличьте пару HL, чтобы она указывала на первый элемент исходного блока

СПАСТИ:

МВИ Д,00Ч

Поместите все элементы из исходного блока в стек

Переместите 00H в D, чтобы очистить регистр D

ДВИЖ Е,М Переместить содержимое, на которое указывает пара HL, в регистр E
НАЖМИТЕ D Поместите содержимое пары регистров DE в стек
ДКР С Регистр декремента C
ИНКС Н Увеличение пары HL
СОХРАНИТЬ Перейти к СОХРАНЕНИЮ, если нулевой флаг не установлен
ДВИГАТЕЛЬ С, В Восстановить длину исходного блока в регистре C из регистра B
МОВ Д,М Сохранить адрес назначения в паре регистров DE
ИНКС Н Увеличение пары HL
ДВИГ Э, М Переместить содержимое, на которое указывает пара HL, в регистр E
МОВА А, Е Чтобы выполнить стабильное копирование (то есть не изменять порядок элементов, выполните копирование из предыдущего местоположения. Итак, просто добавьте длину блока и скопируйте элементы один за другим и продолжайте уменьшать после копирования каждого элемента.
ДОБАВИТЬ С Добавьте содержимое C в аккумулятор
ДКР А Уменьшить содержимое аккумулятора
ДВИЖ Е, А Переместите содержимое аккумулятора в регистр E
XCHG обменяться содержимым пары HL с парой регистров DE
КОПИРОВАТЬ:
ПОП Д
Копировать элементы из стека в место назначения один за другим Извлекать по одному элементу из пары регистров DE и сохранять его в место назначения, на которое в данный момент указывает пара HL
МОВ М,Э Переместить элемент из пары регистров DE в место назначения
ДКР С Уменьшить счетчик.
DCX H Обновите пару HL до следующего свободного места в целевом блоке, чтобы скопировать другой элемент (если он остался)
JNZ КОПИРОВАТЬ Перейти к COPY, если нулевой флаг не установлен.
HLT Остановите программу.