14: MOV [SI-2],AX ;交换AH,AL,排序
15: DEC SI ;向低位再查
16: MOV AH,[SI-2]
17: JMP COMPAR1
18: COMRET:
19: RET
如此,在分支时,在第13条指令做回路,10,11 则比较住址以决定是否完成。这一来,完成结束只有一次,需时 16T,其余所有执行时间皆为4T,较前一回路快了13T 之多。
再试用「终止指令」法,其必要条件为资料中有多余的组合可供选择。一般多以 00H,0FFH 等极端值比较理想,下面且以0FFH作为终止指令,并置于资料终止处。
1: MOV CL,0FFH ;终止检查用
2: SUB AL,AL ;先设为最小值,备用
3: COMPAR:
4: MOV AH,AL ;设AH为低位值
5: COMPAR1:
6: LODSB ;取资料
7: CMP AL,CL ;比是否终止指令?
8: JAE COMRET ;完成
9: CMP AL,AH ;比大、小
10: JAE COMPAR ;高位大,再查
11: MOV [SI-2],AX ;交换AH,AL,排序
12: DEC SI ;向低位再查
13: MOV AH,[SI-2]
14: JMP COMPAR1
15: COMRET:
16: RET
似此,程式较短,其他效果差不多。
这段程式,在处理速度上,还大有油水。因为已经检查过的资料,因为回路关系,还会不断地重复检查,是否能够避免这种情况呢?
事实上,当排序到某住址时,即表示由该住址起,上面已经检查完毕。因此,只要记录下来,下次再查时,将住址还原即可。
1: MOV CL,0FFH ;终止检查用
2: COMPAR0:
3: SUB AL,AL ;先设为最小值,备用
4: COMPAR:
5: MOV AH,AL ;设AH为低位值
6: COMPAR1:
7: LODSB ;取资料
8: CMP AL,CL ;比是否终止指令?
9: JAE COMRET ;完成
10: CMP AL,AH ;比大、小
11: JAE COMPAR ;高位大,再查
12: MOV DI,SI ;暂时保存
13: COMPAR2:
14: MOV [SI-2],AX ;交换AH,AL,排序
15: DEC SI ;向低位再查
16: MOV AH,[SI-2]
17: LODSB ;取排序资料
18: CMP AL,AH ;比是否该排
19: JB COMPAR2 ;是
20: MOV SI,DI ;否,将原位址还原
21: JMP COMPAR0 ;从头再做
22: COMRET:
23: RET
总而言之,程式的变化无穷无尽,尤其是用组合语言制作程式,更是灵活精妙。就像下围棋一般,往往一两个指令就足以将整个局势扭转过来。
程式的效率经常决定在回路上,读者千万不要以为一两个时钟脉冲算不了什么。要知道,汪洋大海,也是由一点一滴的水珠累积而成的。
这段程式还有不少值得深思的,读者们不妨自行研究吧!想得多了,自然会有生花妙笔。
真要作大量的资料排序,还有更有效的方法,也是应用模式分析的原则,先找出资料的「型」。
假如以同样性质的资料为例,为了避免资料一一查找,浪费时间。我们不妨研究一下,是否有可能,直截了当,就把资料依据大小,予以定位,一次排好?
电脑的好处,就在于资料的规律性,我们理应利用这种优点,来找出其排序的模式。
前例曾分为两个模式,一是查找,一是搬移。如果我们把查找改为记录,把搬移改为安排,则情形就大大的不同了。
记录时利用间接定址技巧,每笔取到的资料,皆可视为一个数值,对应于一记录的缓冲区。如果资料中每笔资料总值大于256 且小于 65536,则可以用二字元记录之。再若资料为二进位值,可由 0至 255,即设 512个对应单位。
假定原资料在 DS:SI中,长度在CX中。
首先,设一记录区为:
1: RECORD DB 512 DUP (0)
2: PUSH SI ;程式开始
&nb上一页 [1] [2] [3] [4] [5] [6] 下一页 |