在一个数组中删除所有的和给定数相等的元素

 

题目:;在附加段中有一个首地址为list的未经排序的字数组,在数组的第一个中存放在该数组的长度,数组的首地址已经放入在di寄存器中。 ax寄存器中存放着一个数。
要求:编制一程序,在数组中查找该数, 如果找到此数则把它从数组中删除。 

思路:分析该数组中可能含有不只一个与该数相等的元素,有可能一个都没有,可以同过如下方式来时实现:

           首先找到第一个和该数相等的元素:

               1>若不存在相等的元素,则退出操作。

               2>若存在首个相等的元素,同时记下该元素的位置si,而删除该元素,可以通过将后面的元素前移,

                3>在前移的过程中考虑其是否和该数相等,

                     a. 若相等,除了将指向后元素的游标di前移外,不做其他处理

                    b.若不等, 则将其传送到si所指的位置, 然后同时将 si, di 同时前移

                 goto 3, until 数组的所有元素都被遍历了一遍。 

实现: 考虑到 串查找指令结合重复前缀 repe/repz或者repne/repnz可以实现查找的功能 :

                         scas  es:[di]  :对目的地址操作

                         scasb      :  对字节操作,实现的功能如下

                              (al) -( (di)  )  ,   if df =0 as cld ,  (di)<----(di) +1   , else df=1  as stf, (di)<------(di)-1

                       scasw      :  对字操作,实现的功能如下

                              (ax) -( (dx)  )  ,   if df =0 as cld ,  (di)<----(di) +2   , else df=1  as stf, (di)<------(di)-2

指令的功能: 指令把AL  (或者 AX) 的内容与由(DI)指定的附加段中的一个字节 (或字) 进行比较,但不保存结果,只更具结果设置条件码 (即程序状态字:psw 的值) 。

以上指令,通常和重复前缀 repe/repz 或者 repne/repnz相结合,来比较两个数据串,或者在一个数据串中查找指定数据。

而rep前缀通常和movs(串传送,movsb,movsw),stos(串存储,stosb,stosw), lods(取串,lodsw,lodsb)指令结合使用

格式:  rep   指令

功能:1. 测试cx 是否为0, 若为0,退出该指令的执行,执行该指令的下一条指令;否则转2,

           2..  (cx)<------(cx)-1

           3. 执行其后的指令

           4.重复1.2.3的操作

而带有条件码的重复前缀 repe/repz 或者 repne/repnz,除了在测试 cx,同时,同时还会测试指令执行后对条件码的设置(即对psw的影响,其中的zf 标志位的变化)

对重复前缀码的与指令的关联的情况,不要混淆。

还有一个跳转指令: jcxz  标号  值得提一下 它测试cx是否为0, 为0,则转移到指定的标号。

Code:
  1. ;在附加段中有一个首地址为list的未经排序的字数组,在数组的第一个中存放在该数组的长度,数组的首地址已经放入在di寄存器中。 ax寄存器中存放着一个数。   
  2. ;要求:编制一程序,在数组中查找该数, 如果找到此数则把它从数组中删除。   
  3.   
  4. data segment   
  5.     number dw 9h   
  6.            
  7. data ends   
  8.   
  9. extra segment   
  10.     list dw  0ah,01h, 9h, 3h, 4h, 5h, 9h, 6h, 9h, 0ah, 9h   
  11. extra ends   
  12.   
  13. code segment    
  14.     assume ds:data, es: extra, cs:code   
  15.        
  16. start:   
  17.     mov ax, data   
  18.     mov ds, ax   
  19.     mov ax, extra   
  20.     mov es, ax   
  21.        
  22.     mov di, offset list   
  23.     mov ax, number   
  24.        
  25.     mov dx, 0   
  26.     mov cx, es:[di]   
  27.     add di, 2   
  28.     cld   
  29.        
  30. repne scasw    
  31.        
  32.   jcxz exit   
  33.        
  34.    inc dx      
  35.    mov si, di   
  36.    sub si, 2   
  37. lo:   
  38.     cmp ax, es:[di]   
  39.     jne  next   
  40.     inc dx   
  41.     jmp next1   
  42.        
  43. next:   
  44.      mov bx, es:[di]   
  45.      mov es:[si], bx   
  46.      add si, 2    
  47. next1:   
  48.      add di, 2   
  49.      loop lo   
  50.         
  51. exit:   
  52.      sub es:list[0], dx   
  53.      ;xchg es:list[0], dx   
  54.         
  55.      add dl, 30h   
  56.      mov ah,02h   
  57.      int 21h   
  58.         
  59.      mov ah,4ch   
  60.      int 21h   
  61.            
  62. code ends   
  63.     end start   
  64.       

after note:

Code:
  1. ;;在附加段中有一个首地址为list的未经排序的字数组,在数组的第一个中存放在该数组的长度,数组的首地址已经放入在di寄存器中。 ax寄存器中存放着一个数。   
  2. ;要求:编制一程序,在数组中查找该数, 如果找到此数则把它从数组中删除。   
  3.   
  4. data segment   
  5.     number dw 9h   
  6.            
  7. data ends   
  8.   
  9. extra segment   
  10.     list dw  0ah,01h, 9h, 3h, 4h, 5h, 9h, 6h, 9h, 0ah, 9h   
  11. extra ends   
  12.   
  13. code segment    
  14.     assume ds:data, es: extra, cs:code   
  15.        
  16. start:   
  17.     mov ax, data   
  18.     mov ds, ax   
  19.     mov ax, extra   
  20.     mov es, ax   
  21.        
  22.     mov di, offset list   
  23.     mov ax, number   
  24.        
  25.     mov dx, 0         ; use to store the number of  equal elements    
  26.     mov cx, es:[di]   ; mov the number of the array's elements to cx   
  27.     add di, 2         ; set di as the address of the first element   
  28.     cld               ; set the df of psw  to 0, the direction is up     
  29.        
  30. repne scasw           ; scan the number in ax, until cx=0 or find the first equal element    
  31.   
  32.    jcxz exit          ; can't find the equal element in the array , goto exit   
  33.        
  34.    inc dx             ; make the the number of equal elements increase 1, as one has been found    
  35.    mov si, di         ; save  the address of the first equal element   
  36.    sub si, 2          ; as di point to the address of the next element of the equal element   
  37. lo:   
  38.     cmp ax, es:[di]   ; compare the next word     
  39.     jne  next         ; if not equal goto next    
  40.     inc dx            ; if equal , increase  dx    
  41.     jmp next1         ;         do other process   
  42.        
  43. next:                 ; if not equal, mov this element to si   
  44.      mov bx, es:[di]   
  45.      mov es:[si], bx   
  46.      add si, 2        ; change  si to the new first location    
  47. next1:   
  48.      add di, 2        ; change di to point to the next remaider element    
  49.      loop lo   
  50.         
  51. exit:   
  52.      sub es:list[0], dx   ; set the new array's length   
  53.      ;xchg es:list[0], dx   
  54.         
  55.      ;display the number of the equal elements  in the array   
  56.      add dl, 30h      
  57.      mov ah,02h   
  58.      int 21h   
  59.         
  60.      ;the exit dos system call   
  61.      mov ah,4ch   
  62.      int 21h   
  63.            
  64. code ends   
  65.     end start   
  66.     。   
  67.   

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值