题目:;在附加段中有一个首地址为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
58.
59. mov ah,4ch
60. int
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. goto
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. if not equal goto
40. if
41. do
42.
43. next: ; if not equal, mov this
44. mov bx, es:[di]
45. mov es:[si], bx
46. new
47. next1:
48. add di, 2 ; change di to point to the next remaider element
49. loop lo
50.
51. exit:
52. new
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
59.
60. ;the exit dos system call
61. mov ah,4ch
62. int
63.
64. code ends
65. end start
66. 。
67.