我希望编写一个汇编语言程序来从数据序列中删除重复项。 (30 字节)且未排序,

问题描述 投票:0回答:1

我收到了微处理器课程作业的问题陈述: 编写一个ALP(8085微处理器),从内存段中删除从2000H开始的30字节数据的重复数据字节(像数组一样连续)。这里删除意味着将删除的内存位置处的所有下一个数据字节向左移动。假设数组未排序。

尝试编写代码,但发现写起来太复杂。得到逻辑 - 一个数字,检查数组中的所有剩余字节(在它前面)。然后,如果在 CMP 之后找到匹配项,则将数据向左移动(使用额外的内存)。之后,对下一个编号执行相同的过程。发现管理嵌套循环的不同计数很困难。

arrays assembly microprocessors drop-duplicates 8085
1个回答
0
投票

得到逻辑 - 一个数字,检查数组中的所有剩余字节(在它前面)。然后,如果在 CMP 之后找到匹配项,则将数据向左移动(使用额外的内存)。之后对下一个编号执行相同的步骤。

我编写了下一个程序,其运行方式与您所描述的非常相似。它在 DOSBox 中运行良好。你可以研究一下它的逻辑,然后开始翻译它为

  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
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.