变原用标题,并将分散在各处若干不同之段,列述如下:
189: MASK PROC NEAR
190: MOV DX,3C4H
191: MOV AL,2
192: OUT DX,AL
193: MOV DX,3C5H
194: MOV AL,PCOLOR
195: OUT DX,AL
196: RET
197: MASK ENDP
…
380: MOV DX,03CEH
381: MOV AL,3
382: OUT DX,AL
383: MOV AL,18H
384: INC DX
385: OUT DX,AL
386: RET
…
490: MOV DX,3CEH
491: MOV AL,3
492: OUT DX,AL
493: MOV DX,3CFH
494: MOV AL,0H
495: OUT DX,AL
496: RET
…
589: CROSS PROC NEAR
590: MOV DX,3C4H
591: MOV AL,2
592: OUT DX,AL
593: INC DX
594: MOV AL,0FH
595: OUT DX,AL
596: RET
597: CROSS ENDP
…
这样的段落有十多处,看来每个都略有不同,似乎不能合并。然而仔细分析,显然是程式师训练不够,把一个非常有规则的程式,安排得非常紊乱,以致到这个地步。 我们先归纳问题,决定如何合并。第一,上述各段程式,应该统一作为子程式;第二,全部变数只有四个,其中两个是传送值,两个是输出入埠。后者有连续关系,等于只有一个。因此,在调用此子程式前,应先令DX为输出入埠,再将变数装入AX中,一次调用即可。此子程式如下:
300: SUB:
301: OUT DX,AL
302: INC DX
303: MOV AL,AH
304: OUT DX,AL
305: RET
这样简短的子程式,有无必要,端视时空的效益而定。不论怎样整理,都远比原来的要好。
另外有种情况,更为可怕,就是在键盘输入后,用流程方式,一一比较输入码,再一一分别处理。
比如说,为了检查游标键的左、右、上、下等八个方向的移动,以便作相应的处理,程式居然写成:
100: PP1: MOV AH,0
101: INT 16H
102: CMP AX,4800H ;↑键
103: JNE NEXT1
104: CALL MOVDATA ;SET BUFFERS
105: CALL SETDLT ;SET INCREMENT
106: NXT01:
107: CALL DOTUP
108: LOOP NXT01
109: CALL XORDOT ;SET NEW DOT
110: CALL XYDISP ;DISP NEW XXX,YYY
111: JMP PP1
112: NEXT1:
113: CMP AX,5000H ;↓键
114: JNE NEXT2
115: CALL MOVDATA ;SET BUFFERS
116: CALL SETDLT ;SET INCREMENT
117: NXT02:
118: CALL DOTDOWN
119: LOOP NXT02
120: CALL XORDOT ;SET NEW DOT
121: CALL XYDISP ;DISP NEW XXX,YYY
122: JMP PP1
123: NEXT2:
124: CMP AX,4B00H ;←键
125: JNE NEXT3
…
这段程式总共要检查八次,才能确定是否有游标移动以及哪个游标在移动。然后,还要一一检查其他变化,共有十八种有效码。我实在佩服这种程式师,不但有无比的耐性,还有非凡的想像力,居然能把一段极为简单平凡的程式,写得这样的精彩动人!
如果是我,我会写得毫无