我收到了微处理器课程作业的问题陈述: 编写一个ALP(8085微处理器),从内存段中删除从2000H开始的30字节数据的重复数据字节(像数组一样连续)。这里删除意味着将删除的内存位置处的所有下一个数据字节向左移动。假设数组未排序。
尝试编写代码,但发现写起来太复杂。得到逻辑 - 一个数字,检查数组中的所有剩余字节(在它前面)。然后,如果在 CMP 之后找到匹配项,则将数据向左移动(使用额外的内存)。之后,对下一个编号执行相同的过程。发现管理嵌套循环的不同计数很困难。
得到逻辑 - 一个数字,检查数组中的所有剩余字节(在它前面)。然后,如果在 CMP 之后找到匹配项,则将数据向左移动(使用额外的内存)。之后对下一个编号执行相同的步骤。
我编写了下一个8086程序,其运行方式与您所描述的非常相似。它在 DOSBox 中运行良好。你可以研究一下它的逻辑,然后开始翻译它为8085。
ORG 256 ; Create .COM program
call Print ; Shows the situation 'before'
mov bx, txt ; BX points at the ref.item
mov dx, 30-1 ; DX is # of items that follow the ref.item
OuterLoop:
lea di, [bx+1] ; DI and SI point at the remaining items
mov si, di ; that follow the ref.item
mov cx, dx ; CX is # of items we read and possibly write
InnerLoop:
mov al, [si]
inc si
cmp al, [bx] ; Compare current item to the ref.item
je Skip ; Is a duplicate, so don't keep it
mov [di], al
inc di
inc dx ; Exists just to counteract the `dec dx` that follows
Skip:
dec dx ; Remaining array gets shorter (at its high end)
dec cx
jnz InnerLoop
inc bx ; Move to the following ref.item, consequently the
dec dx ; remaining array gets shorter (at its low end)
jnz OuterLoop
mov byte [di], "$" ; Add string terminator for DOS
Print:
mov dx, txt
mov ah, 09h ; DOS.PrintString
int 21h
ret
; -----------------------
txt: db 'abcdefaghdijklmncopqrstuvwxyza$'
发现管理嵌套循环的不同计数很困难。
外循环由 DX 计数控制,DX 计数表示参考项之后剩余的项数。
内循环由 CX 计数控制,CX 计数由外循环计数器的当前值初始化。
这里删除意味着将删除的内存位置处的所有下一个数据字节向左移动。
我的解决方案不包含单独的左移循环。左移的效果是通过跳过重复项的写入来获得的。
输出:
abcdefaghdijklmncopqrstuvwxyza abcdefghijklmnopqrstuvwxyz