AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > 汇编语言

汇编语言---套装软件制作(2)

51自学网 http://www.wanshiok.com


    我们先归纳问题,决定如何合并。第一,上述各段程式,应该统一作为子程式;第二,全部变数只有四个,其中两个是传送值,两个是输出入埠。后者有连续关系,等于只有一个。因此,在调用此子程式前,应先令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
  …
    这段程式总共要检查八次,才能确定是否有游标移动以及哪个游标在移动。然后,还要一一检查其他变化,共有十八种有效码。我实在佩服这种程式师,不但有无比的耐性,还有非凡的想像力,居然能把一段极为简单平凡的程式,写得这样的精彩动人!
    如果是我,我会写得毫无趣味:
  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     ; 如有必要,可先
                                    ; 设好参数
    这样合并一下,效果决不止高上十倍,等到真正学会了程式的技巧,写作时速度也可以提高数倍。

 
 

上一篇:Casl汇编语言辅导(1)  下一篇:汇编语言---套装软件制作(1)