8085 Программа для копирования исходного блока в целевой блок с перекрывающимся адресом памяти
Задача состоит в том, чтобы скопировать данные из некоторого исходного блока в некоторый целевой блок при условии, что целевой блок имеет перекрывающийся адрес памяти с исходным блоком. Данные нельзя просто переместить из исходного блока в целевой, потому что целевой блок имеет перекрывающийся адрес памяти, это может привести к переопределению данных, а исходные данные могут быть потеряны без копирования в место назначения.
Решение:
Целью решения является копирование данных из исходного блока в другое временное место, а затем копирование данных оттуда в целевой блок. Таким образом, с помощью этого перекрывающиеся проблемы могут быть легко решены. В качестве временного местоположения можно использовать указатель стека. Сначала данные из исходного блока помещаются в стек, затем все данные извлекаются из стека и сохраняются в целевом блоке памяти.
Алгоритм:
- Загрузите пару HL с расположением исходного блока и инициализируйте указатель стека.
- Переместите длину исходного блока в регистр C и сохраните его копию в регистре B для дальнейшего использования.
- Увеличьте пару HL, чтобы она указывала на первый элемент исходного блока.
- [SAVE] Поместите элемент исходного блока, на который указывает пара HL, на вершину стека.
- Регистр декремента C
- Повторяйте [SAVE] до тех пор, пока регистр C не станет ненулевым. Другими словами, это поместит все элементы исходного блока в стек один за другим.
- Восстановите длину исходного блока из регистра B в регистр C.
- Загрузите пару HL с адресом блока назначения.
- [COPY] вытолкнуть элемент из стека в пару регистров DE.
- Переместите регистр E в адрес назначения, указанный парой HL. Другими словами, скопируйте элемент в целевой блок.
- Декрементный регистр С.
- Увеличьте пару HL, чтобы указать на следующий адрес в блоке назначения
- Повторяйте [COPY] до тех пор, пока регистр C не станет ненулевым. Другими словами, переместите все элементы из исходного блока в целевой блок.
- Остановите программу.
Программа сборки 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 | Остановите программу. |