汇编语言的艺术之三:基本认识

来源:互联网  作者:本站整理
摘要:第一节 应用工具一、对程式的认识写作程式不难,但要写出好程式却不容易。这就好像画图一样,人人都能画,而画出来的图却可能有天壤之别。想作一个好画家,首先要有观察及分析的能力,面对着杂乱的事物,先整理出头绪,找到主题。再在画布上勾出轮廓,这叫做……

第五节  分支处理

比较资料后,作条件分支 (Conditional Jump ),是程式中不可避免的手续。程式一长,分支距离超过 128个字元,条件分支就无法到达。当然,精简程式有时可以避免这种情形,但却不尽然。

处理条件分支的技术很多,其效率端视情况而定。最要紧的是事先规划,要比较些什么?在何种情况下?分支到哪里?做些什么工作等等。

不仅是写程式,人的各种能力,都可以由工作的方式判断出来。智慧高的人,很快就能抓住重点,再分门别类,钜细无遗的理出完整的系统。经过良好训练的专家,则能根据一套法规,逐步地整理归纳,也能推出合情合理的结果来。

老实说,电脑程式的写作技术还没有到成熟的阶段,当今所有的从业人员,都只能算是「拓荒者」,并没有真正的「专家学者」。充其量,像我个人一样,比别人机会好些,天天得以与电脑为伍,多一点经验而已。

因此,目前写程式几乎可以说没有可资遵循的法规,海阔天空,爱怎样写,就怎样写,只要能够使用,程式卖得出去,赚了大钱,就会被人视为大师。

只是这种情况维持不了多久了,初民的壁画,仅具有历史意义。今天的程式师,如果不认清现实,立刻觉醒,多致力于法规的制定,电脑将永远是个不成熟的孩子。一旦这些法规经得住考验,为未来的专家学者奠定基础,那才能真正的被视为大师。

我不讳言我们正朝着这个方向努力,但是,我却不认为做得到。因为电脑的硬体设计在今后的十年内,必然会有重大的突破,谁都难以预测会有什么结果。软体的制作观念虽然不可能有很大的改变,却难免会受到影响。只有各位年轻朋友,你们成长在电脑时代,肯多一分耕耘,必有收获!

下面,且介绍一些我对条件分支的处理技巧:

一、资料的分类

1,位元分类:
      在本书第四章第五节所举的,由输入码作为输出字形的处理依据之例,就是采用位元分类的例证。
      但凡以资料位元作为共同的分类讯息,而且各类皆有独特的处理方式者,皆应以其位元为顺序,用间接定址或分支技巧,作为程式处理之手段。

2,字元分类:
      每一个字元具有 256种排列组合,设若有 128种以内的分类项目,应该取双数分类,否则须用连续分类。
      分类之值,立即可以用间接定址执行。但须注意,各分类的入口标题应先行定义。由于定义必须用到双字元,所以,凡采用连续分类者,其值应乘二。

3,间隔分类:
      在有些情况下,原有资料不容许重新安排,而且其中若干资料已具备分类之特性,这种情况,我们称之为间隔分类。
      在处理此类资料时,应该先将可以作分类处理的资料提取出来,并视为字串,定义在一缓冲区内。当须要类比时,可利用「比对字串」 (SCAS) 的指令以求得其定义位置,再作间接定址。设有
      4700H,4900H,4F00H,5100H,4A2DH,4EABH
  等键盘输入数据。设上述值在AX中,需要作特殊处理,分别进入COD1至COD6等子程式。
  11将资料定义在缓冲器 ABC中,程式则定义在DEF:
    ABC  DW   4700H,4900H,4F00H,5100H,4A2DH,4E2BH
    DEF  DW   COD1,COD2,COD3,COD4,COD5,COD6
  12使DI=ABC,CX=6:
      MOV   DI,OFFSET ABC
      MOV   CX,6
  13由比对字串后,判断是否AX中有上述之值,如有,则用间接定址的方式执行之。
      REPNZ   SCASW             ; 比对六组字串
      JCXZ  NOTHING           ; 没有所比之字串
      SUB   DI,OFFSET ABC+2   ; 得到比对位置值
      CALL  CS:DEF[DI]        ; 或作JMP
        上述之DEF 如果放在DG段中,还可以节省一字元,并可加快速度:
      CALL  DEF[DI]

二、程式的结构

若在程式规划之初,未先做好准备工作,临时想用前述的方法,并非绝不可能。但是,东添一点,西补一段,这种程式不仅会导致测试的麻烦,更可能影响未来的维护和调整。

因此,每当瞭解了工作任务后,需要作间接定址的部份,最好能集中在一个模组内。万一性质不同必须分割,也应该将间接定址的程式,置放在模组的起头处。

这样做的好处很多,一方面便于扩充功能,每次增加定址因素时,不必在程式中寻来找去,立刻可以安排妥当。其次,这种定址的需求,必然与整体功能有关,而且定义表相当于一个目录,把纲领放在前面,按图索骥,一目瞭然。更重要的,是可以表现出程式结构的层次,层次处理是网状流程中最难以掌握的一环,不可不慎。

还有,就是各子程式的标题安排,其位置的先后应以功能的集中性为准。这样做的好处是,如果有可以共用的程式段,很容易就可合并为一,节省空间。

三、次序与条件「真」「假」

条件分支的「时钟数」有二个可能,条件符合时,执行分支为 16T,不符合则为 4T ,且继续下一指令。两者相差有四倍之多,我们正该利用这一特点,速度重要的条件,都应该设为主流程,否则为分流程。

尤其是在需要高速的回路中,分支处理得好坏,效率相去甚远。这种分支需要平时多加小心,培养出良好的习惯。
  CDEF: 
      CMP  AL,'?'
      JZ   ABCD     ; 各比较符号中,'?' 者最少
      LOOP   CDEF     ; NZ条件仅需4T速度较快
  ABCD: 
      ..

四、JMP 与 JMP SHORT

当程式师专心写作或侦错之时,常无法瞻前顾后。然而侦错完毕程式无误时,最好彻底检查一下所有的JMP 指令,经常会大有斩获!

因JMP 需要三字元,而JMP SHORT 只要两个,其条件是所跳越的位址不能超过128 字元。

在程式编译时,若向上JMP 的距离在 128字元以内,编译器会自动译为两字元。往下则不然,如在128 字元内,会再多加一个 NOP指令,不仅浪费一字元且多了两个时钟。

因此,细心检查一下,凡是向下跳,在128 字元以内,皆应改为JMP SHORT 才是。

【相关文章】好搜一下
perl语言详解

perl语言详解

Perl最初的设计者为拉里·沃尔(LarryWall),它于1987年12月18…