组合语言之艺术
第五节 分支处理

  比较数据后,作条件分支 (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,不符合则为 4
T ,且继续下一指令。两者相差有四倍之多,我们正该利用这一特点,速度重要的条件,
都应该设为主流程,否则为分流程。
    尤其是在需要高速的回路中,分支处理得好坏,效率相去甚远。这种分支需要平时
多加小心,培养出良好的习惯。
    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 才是。

上一页    下一页