• 汇编语言的分支程序设计与循环程序设计


    汇编语言的分支程序设计:

    例题1:比较三个无符号数的大小,按照从大到小的顺序排列

    关键的语句是:无符号数,因此所用语句是JAE实现跳转:

    此外比较两个操作数所用的是CMP,交换两个操作数的是XCHG

    书上的代码:

    代码1:这样写法比较占用寄存器,但是寄存器之间交换数值比较快

    ;程序名称:实现三个无符号数的由小到大的排序
    DATAS  SEGMENT
    BUFFER   DB   87,234,123
    DATAS  ENDS
    
    CODES   SEGMENT
                        ASSUME  CS:CODES,DS:DATAS
    START:    MOV   AX,DATAS
                        MOV    DS,AX
                        
                        MOV    SI,OFFSET  BUFFER;把buffer的 偏移量交给变址寄存器SI
                        MOV    AL,[SI]
                        MOV    BL,[SI+1]
                        MOV    CL,[SI+2]
                        CMP        AL,BL  ;比较AL,和BL的大小
                        JAE            NEXT1  ;如果AL>BL转移到next1
                        XCHG   AL,BL;交换AL,和BL
    NEXT1:   CMP     AL,CL  ;比较AL和CL的大小
                        JAE            NEXT2
                        XCHG    AL,CL
    NEXT2:   CMP     BL,CL
                        JAE       NEXT3
                        XCHG    BL,CL
    NEXT3:   MOV      [SI],AL    
                        MOV      [SI+1],BL
                        MOV      [SI+2],CL
                        MOV           AH,4CH
                        INT                21H
    CODES    ENDS
                        END    START
    View Code

     代码2:这样的写法只用了AL,但是寄存器与存储器操作数指教的操作比较慢

     1 ;程序功能,实现三个数的大小排序
     2 DATAS     SEGMENT
     3 BUFFER   DB    87,234,123
     4 DATAS     ENDS
     5 
     6 
     7 CODES      SEGMENT
     8 ASSUME  CS:CODES,DS:DATAS
     9 START:    MOV   AX,DATAS
    10                     MOV   DS,AX
    11                     
    12                     MOV     SI,OFFSET  BUFFER
    13                     MOV     AL,[SI]
    14                     CMP     AL,[SI+1]
    15                     JAE       NEXT1
    16                     XCHG   AL,[SI+1]
    17                     MOV     [SI],AL
    18 NEXT1:   CMP      AL,[SI+2]
    19                     JAE        NEXT2
    20                     XCHG    AL,[SI+2]
    21                     MOV      [SI+1],AL
    22 NEXT2:   MOV       AL,[SI+1]
    23                CMP      AL,[SI+2]
    24                JAE        NEXT3
    25                XCHG     AL,[SI+2]
    26                MOV       [SI+1],AL
    27 NEXT3:   MOV        AH,4CH
    28                     INT         21H
    29 CODES    ENDS
    30                    END        START
    View Code

    例题2:写一个实现一位十六进制的数转换为对应的ASCII码的程序 

    ;程序功能,实现16进制数值转换成对应的ASCII码
    ;原理:但十六进制数值为0到9的时候,对应的ASCII=x+30H
    ; 当十六进制为10到15的时候,对应的ASCII = x+37H

    这里关键的语句是 JA,大于9的话,转移

    之后便是程序跳转指令:JMP,但标号很多的时候,可以用LAB1,LAB2,LAB3这种类型的标号

     1 ;程序功能,实现16进制数值转换成对应的ASCII码
     2 ;原理:但十六进制数值为0到9的时候,对应的ASCII=x+30H
     3 ;            当十六进制为10到15的时候,对应的ASCII = x+37H
     4 DATAS            SEGMENT
     5 XX         DB      4
     6 ASCII     DB      ?
     7 DATAS   ENDS
     8 ;
     9 
    10 CODE     SEGMENT 
    11 ASSUME       CS:CODE,DS:DATAS
    12                      MOV   AX,DATAS
    13                      MOV   DS,AX
    14                      
    15 START:         MOV   AL,XX
    16                           AND    AL,0FH
    17                     CMP   AL,9
    18                     JA     LAB1
    19                     ADD    AL,30H
    20                     JMP    LAB2
    21 LAB1:          ADD     AL,37H
    22 LAB2:          MOV    ASCII,AL
    23                           MOV    AH,4CH
    24                           INT      21H
    25 CODE           ENDS
    26                     END     START
    View Code

     例题3:写一个程序实现ASCII转换成对应的十六进制

     1 ;ASCII 转换为16进制数
     2 DATA     SEGMENT
     3 XX          DB       ?
     4 ASCII      DB      'a'
     5 DATA      ENDS
     6 ;
     7 
     8 CODE      SEGMENT
     9          ASSUME    CS:CODE,DS :DATA
    10 START:            MOV   AX,DATA
    11                         MOV   DS,AX
    12                          MOV    AL,ASCII
    13                          CMP   AL,0
    14 LAB:           JB      LAB5
    15                         MOV   AH,AL
    16                         SUB    AH,'0'
    17                         CMP   AL,'9'
    18                         JBE     LAB6
    19                         CMP   AL,'A'
    20                         JB       LAB5
    21                         MOV   AH,AL
    22                         SUB    AH,'A' -10
    23                         CMP    AL,'F'
    24                         JBE      LAB6
    25                         CMP     AL,'a'
    26                         JB        LAB5
    27                         MOV    AH,AL
    28                         SUB      AH,'a' -10
    29                         CMP      AL,'f'
    30                         JBE        LAB6
    31                         ;
    32 LAB5 :         MOV      AH,-1
    33 LAB6:                          MOV       XX,AH
    34                           MOV       AH,4CH
    35                           INT         21H
    36                           CODE      ENDS
    37                                          END         START
    View Code

    利用地址表实现多向分支

    当要根据某个变量的值,进行多种不同的处理时,就会产生了多向分支,多向分支在高级语言中常常用switch实现,在汇编语言中是使用地址表实现的

    DSEG    SEGMENT

    ……………………

    COMTAB  DW  COMA,COMB,COMC,COMD

                  DW  COME,COMF,COMG,COMH

    DSEG      ENDS

    ……………………

    计算如果地址表内的地址,之后调用路口地址表即可

    之后跳转指令用这个 JMP   COMTAB[BX]

    循环程序设计:

    例题1:用计数法控制循环

     1 ;程序功能,说明根据计数法控制循环体
     2 DSEG        SEGMENT
     3 SUM         DW            ?
     4 DSEG        ENDS
     5 
     6 CSEG            SEGMENT
     7 ASSUME         CS:CSEG
     8 
     9 START:     MOV    AX,40H
    10                     MOV DS,AX
    11                     MOV    SI,0
    12                     MOV CX,1024
    13                     XOR    AX,AX
    14 AGAIN:        ADD  AX,[SI]
    15                     INC        SI
    16                     INC     SI
    17                     LOOP        AGAIN
    18                     ;
    19                     ASSUME  DS:DSEG
    20                     MOV    BX,DSEG
    21                     MOV    DS,BX
    22                     MOV    SUM,AX
    23                     MOV    AH,4CH
    24                     INT       21H
    25                     CSEG    ENDS
    26                                     END    START
    View Code

    本例程中所用的关键指令为LOOP,LOOP指令使用的方法是在初始化CX的初值,每次执行一次LOOP,CX寄存器会减一

    此外,还用了SI这个源地址指针,因为定义的变量时字,所以SI在循环的时候,调用了两次INC,在得到校验和的时候,重新设置了

    数据段寄存器,以便于保存校验和

    例题2:不用乘法指令实行乘法运算

    假设乘法时234*125,不用乘法指令,可以有移位和累加两种方法

    方法一:累加,可以看成是125个234相加,因此循环的时候,循环次数是CX=125

     1 ;程序功能,说明根据计数法控制循环体
     2 DSEG        SEGMENT
     3 SUM         DW            ?
     4 DSEG        ENDS
     5 
     6 CSEG            SEGMENT
     7 ASSUME         CS:CSEG
     8 
     9 START:     MOV    AX,40H
    10                     MOV DS,AX
    11                     MOV    SI,0
    12                     MOV CX,1024
    13                     XOR    AX,AX
    14 AGAIN:        ADD  AX,[SI]
    15                     INC        SI
    16                     INC     SI
    17                     LOOP        AGAIN
    18                     ;
    19                     ASSUME  DS:DSEG
    20                     MOV    BX,DSEG
    21                     MOV    DS,BX
    22                     MOV    SUM,AX
    23                     MOV    AH,4CH
    24                     INT       21H
    25                     CSEG    ENDS
    26                                     END    START
    View Code

    这里用的指令时XOR,自己和自己异或等于0,还有JCXZ这条指令,JCXZ表示但cx寄存器为0的时候跳转

    例题3:把16位的二进制数转换为5位十进制数值,为了简单,设二进制数时无符号的,采用8421BCD码表示十进制数

     1 ;程序功能,实现十六位二进制数转换为十进制数
     2 DSEG        SEGMENT
     3 DATA         DW        23456
     4 BUFFER    DB         5    DUP(0)
     5 JM                DW        10000,1000,100,10,1
     6 DSEG        ENDS
     7 
     8 CSEG            SEGMENT
     9                     ASSUME    CS:CSEG,DS:DSEG
    10         START:MOV AX,SEG    DATA
    11                         MOV DS,AX
    12                         MOV DI,OFFSET  JM
    13                         MOV SI,OFFSET BUFFER
    14                         MOV CX,5
    15                         MOV AX,DATA
    16                         XOR DX,DX
    17         NEXT: MOV BX,[DI]
    18                      ADD DI,2
    19                      DIV BX
    20                      MOV [SI],AL
    21                      INC SI
    22                      MOV AX,DX
    23                      XOR DX,DX
    24                      LOOP NEXT
    25                      MOV AX,4C00H
    26                      INT 21H
    27                      CSEG ENDS
    28                                      END START
    View Code

    这里用了两个比较重要的概念,因为是16位的数值,因此必须明白,在进行16位的除法运算时,商保存在AX中,余数保存在DX中

    在进行8位的除法运算时,AL保存商,AH保存余数

    SEG可以返回变量所在的段值,OFFSET返回变量的偏移值,因此经常可以看到 MOV DI,OFFSET JM等等

    在进行除法运算时,DIV BX隐含的是AX/BX

    例题4

    把一个字符串中的大写字母改成小写字母的程序

     1 ;程序功能,把字符串中的大写字母改成小写字母
     2 DSEG        SEGMENT
     3 STRING   DB  'HOW  arR  YOu I',0
     4 DSEG          ENDS
     5 CSEG         SEGMENT
     6                 ASSUME  CS:CSEG,DS:DSEG
     7         START: MOV AX,DSEG
     8                         MOV DS,AX
     9                         MOV SI,OFFSET STRING
    10         AGAIN: MOV AL,[SI]
    11                         OR   AL,AL
    12                         JZ     OK
    13                         CMP AL,'A'
    14                         JB     NEXT
    15                         CMP AL,'Z'
    16                         JA        NEXT
    17                         OR    AL,20H
    18                         MOV [SI],AL
    19         NEXT:   INC   SI
    20                         JMP  AGAIN
    21             OK:   MOV AX,4C00H
    22                         INT   21H
    23            CSEG  ENDS
    24                            END   START
    View Code

    这里需要注意的是,在字符串后面添加了一个0,这里是用来判断字符串是否为结束完,用OR AL,AL来判断,因为自己和自己相或,得到的是本身,只有和0相或,才能得到0

    因此用JZ来转移到OK,

    此外

    比较CMP AL,'A',如果小的话用的是JB转移,

    判断CMP AL 'Z',如果大于的话JA转移,

     经过上面的判断可以得出AL中是大写字母,因此用OR AL,20H,把大写字母转换为小写字母

    如果上述条件不满足,则INC SI

    例题5

    ;写一个程序判定从地址0040:0000H开始的2048个内存字节党员中是否有字节A
    ;如果有字符A,则把第一个(按地址由小到大为序)含此指定字符的存储单元的地址偏移
    ;送到000:03FEH党员中,如果没有,则把特征值送到0FFFFH送到上述指定单元

     1 ;写一个程序判定从地址0040:0000H开始的2048个内存字节党员中是否有字节A
     2 ;如果有字符A,则把第一个(按地址由小到大为序)含此指定字符的存储单元的地址偏移
     3 ;送到000:03FEH党员中,如果没有,则把特征值送到0FFFFH送到上述指定单元
     4 ;
     5 SEGADDR  = 40H
     6 OFFADDR = 0
     7 COUNT = 2048
     8 KEYCHAR = 'A'
     9 SEGRESU = 0
    10 OFFRESU = 3FEH
    11 ;
    12 CSEG            SEGMENT
    13                     ASSUME  CS:CSEG
    14                     START:MOV AX,SEGADDR
    15                                   MOV DS,AX
    16                                   MOV SI,OFFADDR
    17                                   MOV CX,COUNT
    18                                   MOV AL,KEYCHAR
    19                     NEXT: CMP AL,[SI]
    20                                   JZ OK
    21                                   INC SI
    22                                   LOOP NEXT
    23                                   MOV SI,0FFFFH
    24                     OK:     MOV AX,SEGRESU
    25                                   MOV DS,AX
    26                                   MOV BX,OFFRESU
    27                                   MOV [BX],SI
    28                                   MOV AH,4CH
    29                                   INT 21H
    30                     CSEG   ENDS
    31                                     END  START
    View Code

    代码分析:首先是等号的运用  =  ,常量的定义,类似于define

    在查找的时候,调用CMP AL,[SI],这个查找到的话,调用JZ类似于若相等,则跳转

    例题6

    ;设缓冲区中有一组单字节有符号数,以0为结束标志,写一个程序实现如下功能
    ;把前面5个正数一次送到缓冲区PDATA中,把前面5个负数送到缓冲区MDATA中,
    ;如果正数或者负数不足,则用0补足

     1 ;设缓冲区中有一组单字节有符号数,以0为结束标志,写一个程序实现如下功能
     2 ;把前面5个正数一次送到缓冲区PDATA中,把前面5个负数送到缓冲区MDATA中,
     3 ;如果正数或者负数不足,则用0补足
     4 
     5 MAX_COUNT  = 5
     6 DSEG         SEGMENT
     7 DATA         DB  3,-4,5,6,-7,8,-9,-10,-1,-32,-132,27,58,44,-12,0
     8 PDATA         DB  MAX_COUNT DUP (?)
     9 MDATA    DB  MAX_COUNT DUP (?)
    10 DSEG   ENDS
    11 ;
    12 CSEG            SEGMENT
    13                     ASSUME CS:CSEG,DS:DSEG
    14             START: MOV AX,DSEG
    15                             MOV DS,AX
    16                             MOV CX,MAX_COUNT
    17                             MOV SI,OFFSET PDATA
    18                             MOV DI,OFFSET MDATA
    19                             MOV AL,0
    20             NEXT1: MOV [SI],AL
    21                             MOV [DI],AL
    22                             INC SI
    23                             INC DI
    24                             LOOP NEXT1
    25                             MOV BX,OFFSET DATA
    26                             XOR SI,SI
    27                             XOR DI,DI
    28             NEXT2: MOV AL,[BX]
    29                             INC BX
    30                             CMP AL,0
    31                             JZ OVER
    32                             JG PLUS
    33                             CMP DI,MAX_COUNT
    34                             JAE CONT
    35                             MOV MDATA[DI],AL
    36                             INC DI
    37                             JMP SHORT CONT
    38             PLUS:  CMP SI,MAX_COUNT 
    39                             JAE  CONT
    40                             MOV PDATA[SI],AL
    41                             INC SI
    42             CONT: MOV AX,SI
    43                           ADD AX,DI
    44                           CMP AX,MAX_COUNT +MAX_COUNT
    45                           JB NEXT2
    46             OVER:  MOV AH,4CH
    47                             INT 21H
    48                 CSEG ENDS
    49                             END START
    View Code

    这个题目考了很多地方,当程序需要三个指针的时候,这个时候BX,SI,DI都可以作为指针

    这个题目相当的给力,可以好好看看

    版权所有:转载注明链接地址:http://www.cnblogs.com/fengdashen/p/3704148.html

  • 相关阅读:
    atitit,it人怎么样才容易事业成功?? 有以下五种性格的人容易成功
    atitit。win7 win8 win9 win10 win11 新特性总结与战略规划
    atitit.提升兼容性最佳实践 o9o
    atitit.attilax.com产品 软件项目通用框架类库总结
    atitit. 文件上传带进度条 atiUP 设计 java c# php
    atitit.窗体静听esc退出本窗体java swing c# .net php
    atitit.提升研发管理的利器---重型框架 框架 类库的区别
    atitit.导出excel的设计----查询结果 导出为excel的实现java .net php 总结
    atitit. java跟php的比较..为什么大企业喜欢java 而不是php
    atitit. java jsoup html table的读取解析 总结
  • 原文地址:https://www.cnblogs.com/fengdashen/p/3704148.html
Copyright © 2020-2023  润新知