奇趣技术网 收藏本站
设为主页
商务合作
首页 新闻中心 行业动态 软件新闻 安全资讯 病毒预警 漏洞发布 操作系统 Dos Win9x Win2000 WinXP Win2003 WinVista Linux Unix
数据库 DB2 Access MSSQL MySQL Oracle Sybase 编程技术 ASP PHP JSP CGI/Perl XML .Net C/C++/C# VB VC Delphi Java 汇编
安全技术 安全教学 工具介绍 漏洞利用 病毒防范 入侵检测 防火墙 安全防范 汉化破解 攻击实例 加密解密 技术论坛
中华网络安全联盟 >> 程序开发 >> 汇编 >> 汇编语言---套装软件制作(1)
程序开发
Asp
PHP
JSP
CGI/Perl
XML
.Net
C/C++/C#
Visual Basic
Visual C++
Delphi
Java
汇编语言
  • JDBC专题介绍(1)

  • 全面解析JDBC(9)

  • 全面解析JDBC(6)

  • 全面解析JDBC(5)

  • 全面解析JDBC(4)

  • 全面解析JDBC(1)

  • MySQL中修改密码及访问

  • SQL语法参考

  • 汇编语言---套装软件制作(1)
    字体:

    中华网络安全联盟    作者:佚名    来源:网络转载    时间:2006-3-21

    汇编语言---套装软件制作(1):    程式写完后,还要加工成为可执行的套装软件(Package),一般说来,即使是可以执行的程式,一点错误都没有,离套装软件的程度,却还有一段距离。
        当然,程式侦错也是必经过程之一,有时侦错与程式写作可以同时进行。但有经验的程式师,对全面有了充份的认识,往往会等到程式联接后再行侦错。
        程式完成后的全面侦错,最好不要依靠写程式的人。因为程式师经常不是使用者,他们仅在自己设计的条件下,依其理念进行侦错。当然这种错误必须更正,但最容易发生的错误,却是使用者不小心在输入时,或运用指令时,违背了程式师的理念。这种错误的发生,是不能原谅的,程式本来就是为使用者设计的,如果令使用者不便,程式就失去了应有的价值。
        程式的品管,就在于检测程式是否符合使用者的需求。一般说来,应有专人负责,也有让写作手册的人,兼做品管的工作。这样可以同时对照手册所描述的功能及操作方法,检查两者之间是否一致。
        还有一种常见的品管方式,是在产品完成时,交给完全没有参与程式设计的第三者,在客观的立场,作全面的试用,并提出测试报告或建议书。
        品管合格了,才是包装、手册等最后的工作。这并不是说包装和手册要最后才做,相反的,尤其是使用手册,经常要在程式设计的同时,准备妥当,如此程式师才不会任意所之,脱离主题。
        第一节  测试侦错

        不论使用什么工具,侦错时一定要有清晰的头脑,根据所设定的方式,一步一步地查看流程及指令。
        每个人都会有独特的习惯性错误,最好每次将自己发生的错误记下来,不仅错误会渐渐减少,且在错误发生时,很容易就能找到。
        测试侦错是非常重要的手段,有人认为第一流的程式师不应该犯错,即使犯错,也错得很少。我的看法不一样,并非因为我经常犯错,而且错得离谱。真正的理由是为了适时掌握正确的思考方向,在编程时,有意无意地忽略一些细节,这样反而能一气呵成,不致于再而竭三而衰。
        这就像画图一样,有人喜欢先作草图,有人则习惯由细部画起。不论个人的风格如何,重要的是最后的成果。
        我在写程式之前,首先考虑全体的结构,再把各处的支架备妥,然后考虑有共同特性之处,便一口气写完。而且写时力求快速,以免失去当时的感觉。等到结构大体完成了,最后才去填补一些不太重要的细节。至于正确与否,则全靠测试侦错来修正、弥补。
        这种写法要有很强的整体观念,且对每段程式的性质及功能皆瞭解从何下手。
        我由系统程式到应用工具,大大小小的程式写了不少,对这种写作方法有很深的体会。唯一的缺点是,程式如果太大,超过20KB,我的记忆力就难以负担。(年轻人或许不致如此)但其优点则是结构精简,制作时间极短。以我们的中文系统程式而言,8KB 的程式,连侦错在内,只花了两个月的功夫。
        然而,在训练程式师的过程中,我发现到还是循序渐进较好。每次写完了一段程式,立刻侦错,此段程式正确了,再写下一段。除非有绝对的把握,自信没有问题,否则千万不要等全部程式都写完了,再来调试。到那时,如果发现问题,在各段错综复杂的程式中,要找到错误所在,那是大海捞针了。
        程式发生「当机」的情况,常常是 PUSH 及 POP不平衡所致,也有在做回路时,计数器为负值,以致锁在其中。如果程式分「段」太多,则要特别注意各「段」改变的情况。
        诸如这些细节,最好随时把编程时的假想值记录下来,不要太过相信自己的记忆力,时间一长,程式一大,就什么都忘记了。
        还有一点,在侦错时千万要养成习惯,记录追踪的过程。因为侦错是一种很琐碎的工作,很难一次就发现问题所在,第一次应该是第二次改进的经验。如果不详加记录,每次都要从头做起,将是一种极为痛苦的事。
        不妨把侦错视为猜谜,一种智力的挑战,在遵守一定的规则下,应该是一种有趣的享受。
        第二节  研究改进

        想要把程式写好,一定要不断地研究、改进,由错误中学习,由改进中得到经验,培养出敏锐的观察能力和良好的写作习惯。
        在开始时,这种过程需要付出不少时间,但对一位程式师来说,写程式是终身职业,能不精益求精吗?
        以下举两个实例,以说明如何研究改进已完成的程式。
      1,指令的运用:
        以下面这段通讯处理程式而论,不仅语法及指令完全正确,执行时也毫无错误,是不是还可以加以改进呢?
        1-1 按照前面规定,说明项中已用简化的字串:
        SND-传送  RCV-接收  LET-左  
            RGT-右    VER-直    HOR-横
        1-2 程式师代号为'C'。
        1-3 段名省略。

        1: CSND0:
        2:        MOV    DX,03FDH      ; 输出埠
        3:        MOV    AL,80H
        4:        OUT    DX,AL          ; 输出指令
        5:        MOV    DX,03F8H      ; LSB 速度控制
        6:        MOV    AL,06H          ; 速度=19200/秒
        7:        OUT    DX,AL
        8:        MOV    DX,03F9H      ; MSB 速度控制
        9:        MOV    AL,0          ; 速度=19200/秒
       10:        OUT    DX,AL
       11:        MOV    DX,03FBH      ; 行控制暂存器
       12:        MOV    AL,03H          ; NO PARITY,1
                                          ; STOP,8
       13:        OUT    DX,AL
       14:        MOV    DX,03FCH      ; 通讯控制
       15:        OUT    DX,AL
       16:        MOV    DX,03F9H      ; 中断有效
       17:        MOV    AL,0
       18:        OUT    DX,AL
       19: CSND1:
       20:        MOV    DX,03FDH      ; 状态暂存器
       21:        IN    AL,DX
       22:        TEST    AL,10H          ; 是否可接收?
       23:        JNZ    CRCV0          ; 可
       24:        TEST    AL,20H          ; 通道已清否?
       25:        JZ    CSND1          ; 8250未清
       26:        MOV    AH,1          ; 键盘有输入?
       27:        INT    16H
       28:        CMP    AL,07H          ;  ='CTRL+G'
       29:        JE    CEND          ; 是,完毕
       30:        MOV    DX,03F8H
       31:        OUT    DX,AL          ; 送输入字符
       32:        JMP    CSND1
       33: CRCV0:                  ; 接收
       34:        MOV    DX,03FCH      ; 通讯控制
       35:        MOV    AL,08H          ; 暂停中断
       36:        OUT    DX,AL
       37:        MOV    DX,3F8H
       38:        IN    AL,DX          ; 收字符
       39:        MOV    AH,0EH
       40:        INT    10H          ; 萤屏显示
       41:        MOV    DX,03FCH
       42:        MOV    AL,0BH
       43:        OUT    DX,AL          ; 继续接受
       44:        JMP    CSND1          ; 循环工作
       45: CEND:
       46:        RET              ; 完成

        本段程式共 84 个字元,非常精简,但仍然有节省的余地,要点在DX的数值上。
        DX值由 03F8H到 03FDH,可知 DH 之值不变,只需改变 DL 即可。每改变DX一次,需要三个字元,如仅变DL,只需两个字元。这一指令共用了十一次,除第一次有必要外,其他十次就可以省下10个字元。
        再要斤斤计较,还可以榨出二个字元来,在5至8条中,若用INC  DX 只需要一个字元。
        此外,31,32及43 ,44是浪费的作法,只要在第18条加一标号,就可以省却两个字元输出的指令。另外,还有35及39两条指令,应该合并,一次即将AX设妥,于是,又省下了一个字元。
            先令 DH=3
        1: CSEND0:
        2:        MOV    DL,0FDH       ; 输出埠
        3:        MOV    AL,80H
        4:        OUT    DX,AL          ; 输出指令
        5:        MOV    DL,0F8H       ; LSB 速度控制
        6:        MOV    AL,06H          ; 速度=19200/秒
        7:        OUT    DX,AL
        8:        INC    DX          ; MSB 速度控制
        9:        SUB    AL,AL          ; 速度=19200/秒
       10:        OUT    DX,AL
       11:        MOV    DL,0FBH       ; 行控制暂存器
       12:        MOV    AL,DH          ;NO PARITY,1
                          ; STOP,8
       13:        OUT    DX,AL
       14:        INC    DX          ; 通讯控制
       15:        OUT    DX,AL
       16:        MOV    DL,0F9H       ; 中断有效
       17:        SUB    AL,AL
       18: CSNDA:
       19:        OUT    DX,AL
       20: CSND1:
       21:        MOV    DL,0FDH       ; 状态暂存器
       22:        IN    AL,DX
       23:        TEST    AL,10H          ; 是否可接收?
       24:        JNZ    CRCV0          ; 可
       25:        TEST    AL,20H          ; 通道已清否?
       26:        JZ    CSND1          ; 8250未清
       27:        MOV    AH,1          ; 键盘有输入?
       28:        INT    16H
       29:        CMP    AL,07H          ;  ='CTRL+G'
       30:        JE    CEND          ; 是,完毕
       31:        MOV    DL,0F8H
       32:        JMP    CSNDA          ; 送输入字符
       33: CRCV0:                  ; 接收
       34:        MOV    DL,0FCH       ; 通讯控制
       35:        MOV    AX,0E08H      ; 暂停中断
       36:        OUT    DX,AL          ; 及显示
       37:        MOV    DL,0F8H
       38:        IN    AL,DX          ; 收字符
       39:        INT    10H          ; 萤屏显示
       40:        MOV    DL,0FCH
       41:        MOV    AL,0BH
       42:        JMP    CSNDA          ; 循环工作
       43: CEND:
       44:        RET              ; 完成
        看来似乎这样太小气,可是所谓艺术,就要具备丝毫不苟且的态度,再说由84个字元变成66个字元,省了近百分之廿,而且,速度也快了。这种程式原本就很精简,只有训练有素,追求完美的程式师,才做得到。
        另一种做法,便是将重复的过程写成回路,约可节省廿几个字元。但是,由于时间定律限制,通讯程式颇重时效,回路是否值得,尚要多方面分析,不可轻率决定。

      2,回路的实例:
        前面曾经讨论过,程式的效率,经常决定于回路的处理方式及其技巧。其对空间上影响比较小,但是良好的设计理念,常使速度上有高达十倍,甚至百倍的差异,读者想必已经知道,但是如何能应用已知的技巧,来改进设计的程式呢?
        回路是利用计数器,反复进行相同的程序作业,这种程式,目的就是为了节省空间,相对地,时间上难免有所损失。
            因此,在设计回路时,必须先行考虑清楚: 空间的节省与时间的交换是否值得? 其次,则要充份掌握回路的特色,要用得恰到好处,不可掉以轻心。
            原则上,在回路中,指令要用得精简,流程要非常明确,尤其重要的是,应力求避免在回路中使用缓冲器,最好充份利用暂存器。如果时间效率极为重要,则不妨放弃回路方式。
            有一个显示程式,目的是要将 16*16点阵字形送到萤幕上。对象是Hercules 640*400的图形卡,计分四区交互传送,这是另一个「高科技」界的新鲜奇事,在IBM PC推出时,最高密度的图形态,只有 640X200点阵,那是迁就电视萤幕的扫描方式,先送单线的水平讯号,再送双线,故分两区。Hercules卡为了加高密度,应用Interlace 技术,又在单双水平扫描线中各加了一行,遂成了四区。
            Hercules很适宜中文的显示,如用 16X16字形,正好显示25行,每行40字,与英文完全兼容。若希望有一状态显示栏,则可用 15X15字形,留出24条线供做状态栏。
            遗憾的是在最需要中文的国内,却偏爱CGA,EGA 等密度不足的显示设备。不但售价偏高,功能也不足,弄得不伦不类。
            最理想的还是VGA 显示,计有 640X480之萤幕点阵,不仅空间大,在记忆体中,只有一区,应用非常灵活。
            下面,我们先介绍 Hercules 的显示方法,同时探讨回路的处理方式。
        1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        2: ;HERCULES 中文显示处理程式。            ;
        3: ;输入参数:SI=点阵字形,DI=萤幕位置。        ;
        4: ;          DS =CG,ES= 0B800H(萤幕段)。      ;
        5: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        6: CDSP0:
        7:         MOV     CX,16       ;高16点
        8: CDSP1:
        9:         MOVSW           ;移至萤幕上
       10:         ADD     DI,1FFEH       ;加一区,每区=2000H
       11:         JNS     CDSP2       ;未超越区限,继续
       12:         ADD     DI,8050H       ;超越区限,换区加行
       13: CDSP2:
       14:         LOOP    CDSP1
       15:         RET
        程式到此结束,相当精简,技巧在第10至12条区限的检测方式。一般做法是在检查区限时,用:
             ADD     DI,1FFEH       ; 加区值
             CMP     DI,8000H       ; 最大区限值
             JB      CDSP2       ; 未超过
             SUB     DI,8000H       ; 减去区限
        如此则多了一条4字元的指令,加上4个时钟脉冲,做16次回路就损失64个时钟脉冲值。在全萤幕显示时,以1,000 个字来算,为数就不少了。
        当然,取消了回路速度还可以加快,其结果,则要增加130 个字元,时间则快了 272个时钟脉冲,是否值得,就要看实际需要而定了。
        另一个方法,要增加2个字元,但可快上36个时钟脉冲,其法在第11条上:
       11:         JS      CDSP3
       12:CDSP2:
       13:         LOOP    CDSP1
       14:         RET
       15:CDSP3:
       16:         ADD     DI,8050H
       17:         JMP     CDSP2
        再换一个方法,如果先使 BX 为1FFEH,DX为8050H,则在原程式中,将第10条及12条分别改为:
       10:         ADD     DI,BX
       12:         ADD     DI,DX
        这一来,时钟脉冲快了2个,16次则快更多,如果再加上取消回路,其意义更大。空间原增加 130字元,现仅94字元,时间则省下 304个时钟脉冲。如果全萤幕显示了1,000 个字,在8MHZ频率下,将会加快 1/25 秒的速度。
        在回路中,如果讲求时间效益,应极力避免使用PUSH及POP ,因PUSH需15个时钟脉冲,而POP 则要12个,两者相加是27个时钟脉冲,非常不值得。
        解决方法之一是:设法将欲保留之值贮存在没有用到的暂存器中;再若是固定的常数,也不妨在每次要用时重新置入,祇不过是4个时钟而已。最麻烦是变数值,除了在设计模组之前,妥当地安排外,别无良策。
    字体:
     
    设为主页 收藏本站 联系我们 友情连接 商务合作 网友留言
    Copyright©2006-2008 中华网络安全联盟 All rights reserved.