汇编语言套装软件制作(2)
2007-04-25 09:30:31 来源:WEB开发网121: CALL XYDISP ;DISP NEW XXX,YYY
122: JMP PP1
123: NEXT2:
124: CMP AX,4B00H ;←键
125: JNE NEXT3
…
这段程式总共要检查八次,才能确定是否有游标移动以及哪个游标在移动。然后,还要一一检查其他变化,共有十八种有效码。我实在佩服这种程式师,不但有无比的耐性,还有非凡的想像力,居然能把一段极为简单平凡的程式,写得这样的精彩动人!
如果是我,我会写得毫无趣味:
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 BEG00
112: CALL BE3
113: JMP BEG00
…
120: BE14:
121:? LODSW
122: CMP AH,1FH
123: JGE BE141
124: LOOP BE14
125: POP DI
126: POP CX
127: MOV SI,DI
128: JMP BE142
129: BE141:
130: POP DI
131: POP CX
132: MOV SI,DI
…
150: BE10:
151: CALL BE1
152: JMP BEG00
153: BE20:
154: MOV AX,CX
155:? SUB AX,DX
156: SHL AX,1
157: DEC AX
158: JLE BE2
159:? CALL BE3
160: JMP BEG00
161: BE1:
162:? INC DX
163: ADD CX,DX
164: ADD CX,DX
165: INC CX
166: ADD DI,BUFX
167: CMP DI,BX
168: JLE BE1RET
169: CALL BE01
170: SUB DI,BX
171: BE1RET:
172: RET
…
190: BE01:
191:? MOV AL,1
192: CMP [SI+1],AL
193: JNZ BE011
194: INC BYTE PTR [SI+1]
195: RET
…
200: BE141:
…
全部程式并不大,不过一百多条指令,但是稍加改进,却可以省却廿多条指令,速度也会加快。重点在于106 到113 的分支错误,以致于多出BE10 BE20 BE3 BE01等段程式出来。
照理,BE1 BE3 BE01都不该另设子程式,BE14也应改写,如此,整个程式就完全不同了。
更多精彩
赞助商链接