趣味:
100: PP1: SUB AH,AH
101: INT 16H
102: OR AL,AL
103: JNZ PP1 ;AL 非0无效
104: MOV BH,AL
105: MOV BL,AH
106: SUB BL,47H ;最小之字标键
107: JLE PP1 ;非处理范围
108: SHL BX,1
109: CALL FUNC[BX]
110: JMP PP1
这是主流程,程式短,速度快,维护容易,一眼看过去,有什么错误立刻分明。
…
1000: FUNC DW NEXT02 ;↖
1001: DW NEXT0 ;↑
1002: DW NEXT04 ;↗
1003: DW PPRET ;无效
1004: DW NEXT2 ;←
1005: DW PPRET ;无效
1006: DW NEXT4 ;→
1007: DW PPRET ;无效
1008: DW NEXT12 ;↙
1009: DW NEXT1 ;↓
1010: DW NEXT14 ;↘
…
因为这是子程式,加一段、减一段容易非常。
即使是子程式,也有很大的考究,就以前段来说,在 104至110 之间,就值得三思。
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
首先,104 和105 会重复多次,109 及110 亦然,为什么不合并为一呢?这也是很常见的程式合并手法,两次调用合为一次,速度及空间都较为经济。
在子程式 SETDLT 之前,先调用一次 MOVDATA,另XYDISP也是一样,首先备妥:
3000: SETDATA:
3001: CALL MOVDATA ;假设本程式有他用
3002: SETDLT:
3003: …
…
3100: XYDIDOT:
3101: CALL XORDOT ; 同上
3102: XYDISP:
3103: …
…
再来设计NEXT0 的子程式:
110: NEXT0:
111: CALL SETDATA
112: NXT01:
113: DOTUP 应搬至此,无需设为子程式。
…
120: LOOP NXT01
121: JMP XYDIDOT ; 如有必要,可先
; 设好参数
这样合并一下,效果决不止高上十倍,等到真正学会了程式的技巧,写作时速度也可以提高数倍。二、分支的处理:
分支是程式中不可避免的手段,使用得好,整个程式气势一贯,有行云流水之妙。
前面的例子根本不具分支的条件,故不能算是分支不良,而是程式师观念错误。
下面再举一例,由于分支不良,以致程式支离破碎。这是一则计算拋物线的快速程式,妙在没有用乘除法,也没有任何函数。其中有几段是这样的:
100: BEG00:
101: CMP BP,BUFY
102:? JLE BE7
103: OR CX,CX
104: JG BE20
105: MOV AX,BP
106:? SHL AX,1
107: DEC AX
108: JL BE10
109: BE2:
110: CALL BE1
111: JC