题目:;在附加段中有一个首地址为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,则转移到指定的标号。
- ;在附加段中有一个首地址为list的未经排序的字数组,在数组的第一个中存放在该数组的长度,数组的首地址已经放入在di寄存器中。 ax寄存器中存放着一个数。
- ;要求:编制一程序,在数组中查找该数, 如果找到此数则把它从数组中删除。
- data segment
- number dw 9h
- data ends
- extra segment
- list dw 0ah,01h, 9h, 3h, 4h, 5h, 9h, 6h, 9h, 0ah, 9h
- extra ends
- code segment
- assume ds:data, es: extra, cs:code
- start:
- mov ax, data
- mov ds, ax
- mov ax, extra
- mov es, ax
- mov di, offset list
- mov ax, number
- mov dx, 0
- mov cx, es:[di]
- add di, 2
- cld
- repne scasw
- jcxz exit
- inc dx
- mov si, di
- sub si, 2
- lo:
- cmp ax, es:[di]
- jne next
- inc dx
- jmp next1
- next:
- mov bx, es:[di]
- mov es:[si], bx
- add si, 2
- next1:
- add di, 2
- loop lo
- exit:
- sub es:list[0], dx
- ;xchg es:list[0], dx
- add dl, 30h
- mov ah,02h
- int 21h
- mov ah,4ch
- int 21h
- code ends
- end start
after note:
- ;;在附加段中有一个首地址为list的未经排序的字数组,在数组的第一个中存放在该数组的长度,数组的首地址已经放入在di寄存器中。 ax寄存器中存放着一个数。
- ;要求:编制一程序,在数组中查找该数, 如果找到此数则把它从数组中删除。
- data segment
- number dw 9h
- data ends
- extra segment
- list dw 0ah,01h, 9h, 3h, 4h, 5h, 9h, 6h, 9h, 0ah, 9h
- extra ends
- code segment
- assume ds:data, es: extra, cs:code
- start:
- mov ax, data
- mov ds, ax
- mov ax, extra
- mov es, ax
- mov di, offset list
- mov ax, number
- mov dx, 0 ; use to store the number of equal elements
- mov cx, es:[di] ; mov the number of the array's elements to cx
- add di, 2 ; set di as the address of the first element
- cld ; set the df of psw to 0, the direction is up
- repne scasw ; scan the number in ax, until cx=0 or find the first equal element
- jcxz exit ; can't find the equal element in the array , goto exit
- inc dx ; make the the number of equal elements increase 1, as one has been found
- mov si, di ; save the address of the first equal element
- sub si, 2 ; as di point to the address of the next element of the equal element
- lo:
- cmp ax, es:[di] ; compare the next word
- jne next ; if not equal goto next
- inc dx ; if equal , increase dx
- jmp next1 ; do other process
- next: ; if not equal, mov this element to si
- mov bx, es:[di]
- mov es:[si], bx
- add si, 2 ; change si to the new first location
- next1:
- add di, 2 ; change di to point to the next remaider element
- loop lo
- exit:
- sub es:list[0], dx ; set the new array's length
- ;xchg es:list[0], dx
- ;display the number of the equal elements in the array
- add dl, 30h
- mov ah,02h
- int 21h
- ;the exit dos system call
- mov ah,4ch
- int 21h
- code ends
- end start
- 。