电工学习网

 找回密码
 立即注册

分支程序设计

2015-3-22 09:32| 编辑:电工学习网| 查看: 13262| 评论: 0

   分支程序的基本思想是根据逻辑判断的结果来形成程序的分支,如图,若A成立,则执行P1;否则执行P2。

    分支程序有两种基本结构,如图所示。

    

    它们分别相当于高级语言中的IF_THEN_ELSE语句和CASE语句,适用于要求根据不同条件作不同处理的情况。IF_THEN_ELSE语句可以引出两个分支,CASE语句则可以引出多个分支,不论哪一种形式,它们的共同特点是:运行方向是向前的,在某一种特定条件下,只能执行多个分支中的一个分支。

    

    例1  试编写程序段,实现符号函数。

    分析:变量X的符号函数可表示为:

    程序可通过对符号标志的判别来确定执行哪一分支。

    START: MOV AX,BUFFER    ;(BUFFER)=X

    OR  AX,AX

    JE  ZERO           ;X=0,则转ZERO

    JNS  PLUS            ;X为正数,则转PLUS

    MOV BX,0FFFFH     ;X为负数,则-1送BX

    JMP  CONT1

    ZERO:  MOV BX,0

    JMP  CONT1

    PLUS:  MOV BX,1

    CONT1:   ……

    例2  利用表实现分支。根据AL中各位被置位情况,控制转移到8个子程序P1~P8之一中去。转移表的结构如表1所示。

    分析:对于这种程序关键要找出每种情况的转移地址,从图中可见表地址=表基地址+偏移量, 而偏移量可由AL各位所在位置*2求得。

表1 子程序R1—R8的入口地址表

P1

子程序R1的入口偏移地址

P2

子程序R2的入口偏移地址

P3

子程序R3的入口偏移地址

……
……

…….
……

P7

子程序R7的入口偏移地址

P8

子程序R8的入口偏移地址

    DATA  SEGMENT

    BASE  DW  SR0,SR1,SR2,SR3,   

    SR4,SR5,SR6,SR7

    DATA  ENDS

    CODE  SEGMENT                        

    ASSUME CS:CODE,DS:DATA,ES:DATA

    BEGIN:    PUSH DS

    XOR AX,AX

    PUSH  AX

    MOV AX,DATA                         

    MOV DS,AX                        

    LEA BX,BASE ;表头送BX

    IN  AL,PORT               

    GETBIT: RCR   AL,1    ;右移一位

    JC    GETAD  ;移出位是1?

    INC  BX

    INC   BX     ;修改指针

    JMP  GETBI    

    GETAD: JMP  WORD PTR[BX] ;实现散转

    CODE  ENDS                                  

    END  BEGIN

    例3  将内存中某一区域的原数据块传送到另一区域中。

    分析:这种程序若源数据块与目的数据块之间地址没有重叠,则可直接用传送或串操作实现;若地址重叠,则要先判断源地址+数据块长度是否小于目的地址,若是,则可按增量方式进行,否则要修改指针指向数据块底部,采用减量方式传送。程序如下:

    DATA  SEGMENT

    STR   DB 1000DUP(?)

    STR1  EQU STR+7

    STR2  EQU STR+25

    STRCOUNT EQU 50

    DATA  ENDS

    STACK  SEGMENT PARA  STACK  ‘STACK’

    STAPN  DB  100DUP(?)

    STACK  ENDS

    CODE  SEGMENT

    ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK

    GOO   PROC

    PUSH DS

    SUB  AX,AX

    PUSH AX

    MOV AX,DATA

    MOV DS,AX

    MOV ES,AX

    MOV AX,STACK

    MOV SS,AX

    MOV CX,STRCOUNT

    MOV SI,STR1

    MOV DI,STR2

    CLD

    PUSH SI

    ADD SI,STRCOUNT-1

    CMP SI,DI

    POP  SI

    JL  OK

    STD

    ADD SI,STRCOUNT-1

    ADD DI,STRCOUNT-1

    OK:  REP  MOVSB

    RET

    GOO  ENDP

    CODE  ENDS

    END GOO                  

    

    

    cseg  segment

    main proc  near

    assume cs:cseg, ds:data

    start:

    mov  ax,dseg

    mov  ds,ax

    

    

    exit:  mov  ax,4c00h

    int  21h

    main  endp

    cseg  ends

    end  start

    例4 试根据AL寄存器中哪一位为1(从低位到高位)把程序转移到8个不同的程序分支中去。

    branch_addresses  segment    ; 定义数据段

    branch_table     dw routine_1

    dw routine_2

    dw routine_3

    dw routine_4

    dw routine_5

    dw routine_6

    dw routine_7

    dw routine_8

    branch_addresses  ends

    procedure_select  segment    ; 定义代码段

    main   proc  far        ; 定义主程序main

    assume cs:procedure_select,ds:branch_addresses

    start: 

    push  ds 

    sub   bx,bx 

    push  bx 

    mov   bx,branch_addresses

    mov   ds,bx

    ; 程序的主要部分(寄存器相对寻址)

    cmp   al,0       ; (al)=0?

    je continue     ; (al)为0则转到continue_main_line

    mov   si,0

    l:      shr   al,1        ; 把al逻辑右移1位

    jnc   not_yet       ; CF=0转到not_yet

    jmp   branch_table[si]   ; CF=1转到相应程序分支

    not_yet:     add   si,type branch_table  ; 修改地址add si,2

    jmp   l          ; 无条件跳到l 

    continue:          ; 其它程序段

    … 

    routine_1: 

    …           ; 程序段1

    routine_2: 

    …           ; 程序段2 

    ret 

    main  endp       ; 主程序main结束

    procedure_select ends 

    end   start

    用寄存器间接寻址方式实现跳跃表法的程序如下(仅给出修改后的程序的主要部分):

    ……

    cmp  al,0 

    je   continue 

    lea  bx,branch_table ; branch_table的偏移地址送bx         l: shr  al,1 

    jnc  not_yet     ; CF=0转到not_yet

    jmp  word ptr[bx]   ; CF=1转到相应程序分支

    not_yet: add  bx,type branch_table ; 修改地址

    jmp  l        ; 无条件跳到l

    continue: 

    …… 

    用基址变址寻址方式实现跳跃表法的程序如下(仅给出修改后的程序的主要部分),与前两种寻址方式的主要区别是这里使用了逻辑左移指令,即从al的高位向低位判断,而前两段程序是从al的低位向高位判断。

    ……

    cmp  al,0 

    je   continue

    lea  bx,branch_table 

    mov  si,7*type branch_table   ; 14送si

    mov  cx,8            ; 循环次数8送cx

    l: shl  al,1            ; 把al逻辑左移1位

    jnb  not_yet           ; CF=0转到not_yet

    jmp  word ptr[bx][si]      ; CF=1转到相应程序分支

    not_yet: sub  si,type branch_table    ; 修改地址

    loop l              ; 循环

    continue: 

    ……

    以上多个例子都是既有分支结构又有循环结构,实际上,多数程序都是各种程序结构的组合。而且,循环结构可以看作分支结构的一种特例,它只是多次走一个分支,只在满足循环结束条件时,走另一个分支罢了。

    算法和循环控制条件的选择对程序的工作效率有很大的影响,而循环控制条件的选择又是很灵活的,应该根据具体情况来确定。考虑算法时必须把可能出现的边界情况考虑在内。

    设置逻辑尺是循环控制中很常用的一种方法。除了静态地预置外,还可以在程序中动态地修改标志位的值,以达到控制的目的。

    循环可以有多层结构。多重循环程序设计的基本方法和单重循环程序设计是一致的,应分别考虑各重循环的控制条件及其程序实现,相互之间不能混淆。另外,应该注意在每次通过外层循环再次进入内层循环时,初始条件必须重新设置。

    起泡排序算法是多重循环程序设计中的一种常用方法。

    分支程序结构可以有两种形式。分别相当于高级语言中的IF_THEN_ELSE语句和CASE语句,适用于要求根据不同条件作不同处理的情况。

    IF_THEN_ELSE语句可以引出两个分支,CASE语句则可以引出多个分支,不论哪一种形式,它们的共同特点是:运行方向是向前的,在某一种特定条件下,只能执行多个分支中的一个分支。

    数组排序算法中可以采用折半查找法来提高查找效率。

    CASE结构可以使用跳跃表法实现,使程序能根据不同的条件转移到多个程序分支中去。跳跃表法;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;是一种很有用的分支程序设计方法。

看过《分支程序设计》的人还看了以下文章:

发表评论

最新评论

电工学习网 ( )

GMT+8, 2023-3-26 00:53

Powered by © 2011-2022 www.shop-samurai.com 版权所有 免责声明 不良信息举报

技术驱动未来! 电工学习网—专业电工基础知识电工技术学习网站。

栏目导航: 工控家园 | 三菱plc | 西门子plc | 欧姆龙plc | plc视频教程

返回顶部