Chinaunix首页 | 论坛 | 博客
  • 博客访问: 226408
  • 博文数量: 45
  • 博客积分: 1850
  • 博客等级: 上尉
  • 技术积分: 473
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-11 10:21
文章分类
文章存档

2006年(17)

2005年(28)

我的朋友

分类:

2006-04-09 12:30:36

支程序的设计
分支程序结构有单分支if-then和双分支if-then-else两种基本形式,如果分支处理中又嵌套有分支,或者说具有多个分支走向时,即为逻辑上的多分支形式。
一、用转移指令实现分支
条件转移jcc和无条件转移JMP指令用于实现程序的分支结构,JMP指令仅实现了转移到指定位置,Jcc指令则根据条件转移到指定位置或不转移而顺序执行后续指令序列。如下流程图:

注意的是转移指令实现了转移,但在第一个分支执行完后不会自动跳过第二个分支体,而是根据程序的顺序继续执行指令。若要实现两分支中执行一支,前一个(第一个)分支体后,必须有一条无条件转移指令跳到第二个分支体之后,即分支汇点处。
条件转移语句不支持一般的条件表达式,它是根据当前某些标志位的设置情况实现转移或不转移。
一个典型的单分支结构如下:
      mov ax,X
      sub ax,Y
      jns nonneg
      neg ax
nonneg:
      mov result,ax
例25.1:判断方程是否有实根,若有实根则将字节变量tag置1,否则置0(假设a、b、c均为字节变量,表达-127——+127的数据)。
分析:二元一次方程有根的条件是:  。依据题意,首先计算出b的平方和4ac,然后比较两者大小,根据比较的结果分别给tag赋不同的值。
    .model small
    .stack 256
    .data
    _a  db ?
    _b  db ?
    _c  db ?
tag     db ?
    .code
    .startup
    mov al,_b
    imul al
    mov bx,ax
    mov al,_a
    imul _c
    mov cx,4
    imul cx
    cmp bx,ax
    jge yes
    mov tag,0
    jmp done
yes: mov tag,1
done: .exit 0
    end
如果分支较多,我们可以借鉴中断向量表的工作原理,构造一个入口地址表,如下例:
例25.2:程序根据键盘输入的1——8数字转向不同的处理程序段
分析:在数据段定义一个存储区,顺序存放8个处理程序段的起始地址。由于所有程序都在一个代码段,所以用字定义伪指令dw存入偏移地址。如果输入的不是1——8数字,系统自动重新提示输入,如果数字有效,则形成表中的正确偏移,并按地址表跳转。
    .model small
    .stack 256
    .data
msg db 'input number(1--8):',0dh,0ah,'$'
msg1 db 'chapter1:11111111111111111111',0dh,0ah,'$'
msg2 db 'chapter2:22222222222222222222',0dh,0ah,'$'
msg3 db 'chapter3:33333333333333333333',0dh,0ah,'$'
msg4 db 'chapter4:44444444444444444444',0dh,0ah,'$'
msg5 db 'chapter5:55555555555555555555',0dh,0ah,'$'
msg6 db 'chapter6:66666666666666666666',0dh,0ah,'$'
msg7 db 'chapter7:77777777777777777777',0dh,0ah,'$'
msg8 db 'chapter8:88888888888888888888',0dh,0ah,'$'
table dw disp1,disp2,disp3,disp4,disp5,disp6,disp7,disp8
    .code
    .startup
start:
    mov dx,offset msg
    mov ah,9
    int 21h
    mov ah,1
    int 21h
    cmp al,'1'
    jb start
    cmp al,'8'
    ja start
    and ax,000fh
    dec ax
    shl ax,1
    mov bx,ax
    jmp table[bx]
start2:
    mov ah,9
    int 21h
    .exit 0
    ;
disp1:
    mov dx,offset msg1
    jmp start2
disp2:
    mov dx,offset msg2
    jmp start2
disp3:
    mov dx,offset msg3
    jmp start2
disp4:
    mov dx,offset msg4
    jmp start2
disp5:
    mov dx,offset msg5
    jmp start2
disp6:
    mov dx,offset msg6
    jmp start2
disp7:
    mov dx,offset msg7
    jmp start2
disp8:
    mov dx,offset msg8
    jmp start2
   
    end
二、用条件控制伪指令实现分支
MASM60引入.IF、.ELSEIF、.ELSE和.ENDIF伪指令,他们类似高级语言中的IF、THEN、ELSE和ENDIF,这些伪指令在汇编时要展开,自动生成对应得比较和条件转移指令序列,实现程序的分支,利用条件控制伪指令可以简化分支结构的编程。
条件控制伪指令的格式如下:
.IF 条件表达式            ;条件为真(值非0),执行分支
    分支体
[.ELSEIF 条件表达式       ;前面IF[以及前面ELSEIF]条件为假(值为0),
                          ;并且当前ELSE条件为真,执行分支体
      分支体  ]
[.ELSE                    ;前面IF[以及前面ELSEIF]条件为假,
                          ;执行分支体
      分支体  ]
.ENDIF                    ;分支体结束
方括号内的部分可选,条件表达式允许的操作符如下表:

如上面的典型单分支结构,可以修改如下:
mov ax,X
sub ax,Y
.IF AX <0
    neg ax
.ENDIF
mov result,ax
汇编程序在翻译相应条件表达式时,将生成一组功能等价的比较、测试和转移指令,值得一提的是要注意条件表达式比较的两个数值是作为无符号数还是作为有符号数,因为他们将影响产生的条件转移指令。对于条件表达式中的变量,若是用db、dw、dd定义的,则一律作为无符号数,若需要进行带符号数的比较时,这些变量在定义时须用相应的带符号数定义语句来定义,依次为SBYTE、SWORD、SDWORD。采用寄存器或常数作为表达式的数值参加比较时,默认也是无符号数,如果作为有符号数,可以利用sbyte ptr 或 sword ptr 操作符指明。若其中一个数值为有符号数,则条件表达式强制另一个数作为有符号数进行比较。
例25.3:用条件控制伪指令实现有根判断的源程序。
    .model small
    .stack 256
    .data
_a  sbyte ?
_b  sbyte ?
_c  sbyte ?
tag byte ?
    .code
    .startup
    mov al,_b
    imul al
    mov bx,ax
    mov al,_a
    imul _c
    mov cx,4
    imul cx
    .if sword ptr bx >=ax
      mov tag,0
    .else
      mov tag, 1
    .enif
    .exit 0
    end  
其生成的lst文件如下:
 
Microsoft (R) Macro Assembler Version 6.11      04/09/06 11:41:54
l25-3.asm           Page 1 - 1

        .model small
        .stack 256
 0000        .data
 0000 00   _a  sbyte ?
 0001 00   _b  sbyte ?
 0002 00   _c  sbyte ?
 0003 00   tag byte ?
 0000        .code
        .startup
 0000      :
 0000  BA ---- R    *     mov    dx, DGROUP
 0003  8E DA     *     mov    ds, dx
 0005  8C D3     *     mov    bx, ss
 0007  2B DA     *     sub    bx, dx
 0009  D1 E3     *     shl    bx, 001h
 000B  D1 E3     *     shl    bx, 001h
 000D  D1 E3     *     shl    bx, 001h
 000F  D1 E3     *     shl    bx, 001h
 0011  FA     *     cli   
 0012  8E D2     *     mov    ss, dx
 0014  03 E3     *     add    sp, bx
 0016  FB     *     sti   
 0017  A0 0001 R      mov al,_b
 001A  F6 E8       imul al
 001C  8B D8       mov bx,ax
 001E  A0 0000 R      mov al,_a
 0021  F6 2E 0002 R      imul _c
 0025  B9 0004       mov cx,4
 0028  F7 E9       imul cx
        .if sword ptr bx >= ax
 002A  3B D8     *     cmp    sword ptr bx, ax
 002C  7C 07     *     jl     @C0001
 002E  C6 06 0003 R 00        mov tag,0
        .else
 0033  EB 05     *     jmp    @C0003
 0035      :
 0035  C6 06 0003 R 01        mov tag, 1
        .endif
 003A      :
        .exit 0
 003A  B8 4C00     *     mov    ax, 04C00h
 003D  CD 21     *     int    021h
        end
Microsoft (R) Macro Assembler Version 6.11      04/09/06 11:41:54
l25-3.asm           Symbols 2 - 1
 

Segments and Groups:
                N a m e                 Size     Length   Align   Combine Class
DGROUP . . . . . . . . . . . . . GROUP
_DATA  . . . . . . . . . . . . . 16 Bit  0004   Word   Public  'DATA' 
STACK  . . . . . . . . . . . . . 16 Bit  0100   Para   Stack   'STACK' 
_TEXT  . . . . . . . . . . . . . 16 Bit  003F   Word   Public  'CODE' 

Symbols:
                N a m e                 Type     Value    Attr
@CodeSize  . . . . . . . . . . . Number  0000h 
@DataSize  . . . . . . . . . . . Number  0000h 
@Interface . . . . . . . . . . . Number  0000h 
@Model . . . . . . . . . . . . . Number  0002h 
@Startup . . . . . . . . . . . . L Near  0000   _TEXT 
@code  . . . . . . . . . . . . . Text     _TEXT
@data  . . . . . . . . . . . . . Text     DGROUP
@fardata?  . . . . . . . . . . . Text     FAR_BSS
@fardata . . . . . . . . . . . . Text     FAR_DATA
@stack . . . . . . . . . . . . . Text     DGROUP
_a . . . . . . . . . . . . . . . Byte  0000   _DATA 
_b . . . . . . . . . . . . . . . Byte  0001   _DATA 
_c . . . . . . . . . . . . . . . Byte  0002   _DATA 
tag  . . . . . . . . . . . . . . Byte  0003   _DATA 
    0 Warnings
    0 Errors
阅读(2055) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~