一、实验要求

  1. 编写 Q = a + (b - c) * d 的程序。(a、b、c、d 为 0~9 间的正整数)要求:a、b、c、d 均从键盘输入,计算结果在虚拟终端上显示

分析如下:
该内容由于涉及到对输入/输出设备的操作,需要利用 DOS 功能调用的 INT 21H 指令来实现。键盘输入一个字符可用 01H 调用,输入字符串可用 0AH 调用;显示器显示一个字符可用 02H 调用,字符串输出可用 9 调用。另外完成表达式的计算,将各变量进行定义并赋值,然后按照计算顺序从内到外依次操作,最后保存结果,在虚拟终端上显示。

  1. 在DS数据段偏移地址为DATA开始的顺序80个单元中,存放着某班40个同学的微机原理考试成绩。请编程统计>=90分,80分-89分,70分-79分,60分-69分以及<60分的人数,将统计结果放在当前数据段偏移地址为BUFFER的顺序单元中。并在虚拟终端上显示各分数段的人数

分析如下:该内容分为两部分:
(1)由于涉及整数循环比较,需要利用 CMP 指令;分支结构用到 JC 条件转移指令,并将统计数据放在数据段进行存储;
(2)虚拟终端上显示需要利用 DOS 功能调用的 INT 21H 指令来实现。

指令格式功能说明
CALLCALL OPRD过程调用指令(1)OPRD为目的地址;(2)过程调用可分为段内调用和段间调用两种,寻址方式也可以分为直接寻址和间接寻址两种;(3)本指令不影响标志位。
JCJC 标号条件转移指令(1)JC 为根据标志位 CF 进行转移的指令;(2)CF = 1,转至标号处执行。
CMPCMP OPRD1,OPRD2比较指令(1)OPRD1为任意通用寄存器或存储器操作数,OPRD2为任意通用寄存器或存储器操作数,立即数,也可用作源操作数OPRD2;(2)对标志位的影响同SUB指令,完成的操作与SUB指令类似,唯一的区别是不将OPRD1-OPRD2的结果送回OPRD1,而只是比较;(3)在8086/8088 指令系统中,专门提供了一组数据带符号数比较大小后,实现条件转移的指令。

在这里插入图片描述

  1. 从键盘上输入1个数(不大于5位,以回车键结束),判断其奇偶性,如果是奇数,屏幕上显示”It is odd”,否则显示”It is even”

分析如下:
每次输入一个数(对应 ASCII 30H~39H),如输入回车键(对应 ASCII 0DH)判断为输入结束。
(1)根据输入数据最后一位是否为 1,判断奇偶性,利用 AND 操作,例如 AND BL, 01H,0 表示清除对应位,1 表示保留对应位操作;
(2)虚拟终端上显示需要利用 DOS 功能调用的 INT 21H 指令来实现。

  1. 从键盘上输入N个字符(N<16),求这N个字符中’A’的个数,并将’A’的个数显示在屏幕上

分析如下:
每次输入一个字符,循环 16 次,如循环退出的条件:输入回车键(对应 ASCII 0DH),判断为输入结束。
(1)字符 A 的 ASCII 为 41H,若输入的字符为 A,通用寄存器加 1,并保存;
(2)虚拟终端上显示需要利用 DOS 功能调用的 INT 21H 指令来实现。
数字 0~9 对应的 ASCII 码(十进制)为 48~57
大写字母 A~Z 对应的 ASCII 码(十进制)为 65~90
小写字母 a~z 对应的 ASCII 码(十进制)为 97~122

  1. 已知BUF1中有N1个按从小到大的顺序排列的互不相等的无符号数,BUF2中有N2个从小到大的顺序排列的互不相等的无符号数。编写程序将BUF1和BUF2中的数合并到BUF3中,使在BUF3中存放的数互不相等且按从小到大的顺序排列

分析如下:
(1)BUF1 中的数小于 BUF2 中的数,将 BUF1 中的数放入 BUF3 中,BUF1 中的数已经合并到 BUF3 中,将 BUF2 中剩余的数存入 BUF3 中;
(2)虚拟终端上显示需要利用 DOS 功能调用的 INT 21H 指令来实现。
SI:存放源串的偏移地址;
DI:存放目的串的偏移地址;
CX:存放循环计数值;
AX、BX:临时使用的寄存器。

二、实验目的

学习顺序、分支、循环结构以及子程序的编程设计。

三、实验代码及实验结果

实验1

实验代码:

DATAS    SEGMENT
         MESS1 DB 'PLEASE INPUT A', 0DH,0AH,'$'
         MESS2 DB 'PLEASE INPUT B', 0DH,0AH,'$'
         MESS3 DB 'PLEASE INPUT C', 0DH,0AH,'$'
         MESS4 DB 'PLEASE INPUT D', 0DH,0AH,'$'
         MESS5 DB 'Q=','$'
DATAS    ENDS
        

EXTRA   SEGMENT   ;附加段 
    
EXTRA   ENDS

        
STACK   SEGMENT PARA STACK    'STACK';堆栈段
STAPN   DB      100 DUP (00H)   ;定义100字节空间
TOP EQU LENGTH STAPN        
STACK ENDS

 
CODE    SEGMENT
MAIN    PROC FAR        ;过程定义语句    
                 ;说明4个寄存器分别和哪些段有关 
        ASSUME  CS:CODE,DS:DATAS,ES:EXTRA,SS:STACK
START:                 ;在下面写代码
        MOV AX,DATAS
        MOV DS,AX
        
        MOV AX,EXTRA
        MOV ES,AX
        
        MOV AX,STACK
        MOV SS,AX  
        ;;;;程序开始;;;
        ;数据B 的输入
        MOV DX,OFFSET MESS2
        MOV AH,09H
        INT 21H
        MOV AH,01H
        INT 21H
        AND AL,0FH         
        MOV BL,AL 
        
        ;数据C 的输入
        MOV DL,0DH
        MOV AH,02H
        INT 21H
        
        MOV DL,0AH
        MOV AH,02H
        INT 21H
        
        MOV DX,OFFSET MESS3
        MOV AH,09H
        INT 21H
        MOV AH,01H
        INT 21H
        AND AL,0FH         
        SUB BL,AL 
        
        ;数据D 的输入  
        MOV DL,0DH
        MOV AH,02H
        INT 21H
        
        MOV DL,0AH
        MOV AH,02H
        INT 21H
        
        MOV DX,OFFSET MESS4
        MOV AH,09H
        INT 21H
        MOV AH,01H
        INT 21H
        AND AL,0FH         
        MUL BL
        MOV BL,AL 
        
        ;数据A 的输入
        MOV DL,0DH
        MOV AH,02H
        INT 21H
        
        MOV DL,0AH
        MOV AH,02H
        INT 21H
         
        MOV DX,OFFSET MESS1
        MOV AH,09H
        INT 21H
        MOV AH,01H
        INT 21H
        AND AL,0FH         
        ADD AL,BL
        
        ;进制转化
        MOV AH,00H
        AAA
        ADD AX,3030H
        MOV BX,AX
        
        ;结果显示
        MOV DL,0DH
        MOV AH,02H
        INT 21H
        
        MOV DL,0AH
        MOV AH,02H
        INT 21H
        
        MOV DX,OFFSET MESS5
        MOV AH,09H
        INT 21H  
        
        MOV DL,BH
        MOV AH,02H
        INT 21H
        
        MOV DL,BL
        MOV AH,02H
        INT 21H  
        
        ;退出dos
        MOV AH,4CH
        INT 21H
        
        RET
MAIN    ENDP   ;MAIN过程结束                    
CODE    ENDS   ;代码段结束
END MAIN   ;整个源代码结束

实验结果:
在这里插入图片描述

实验2

实验代码:

SHUJU SEGMENT
    DATA  DB 91,74,64,47,98,72,85,83,65,57,88,79,85,95,70,89,49,46,85,77,87,99,82,66,78,48,72,65,99,89,74,93,73,100,54,92,75,58,86,50
BUFFER 4 DUP(0)
STR0 DB "  SCORES ARE: $"
STR1 DB "NUMBER OF SCORE ABOVE 90 POINTS: $" 
STR2 DB "NUMBER OF SCORE BETWEEN 80 POINTS AND 89 POINTS: $" 
STR3 DB "NUMBER OF SCORE BETWEEN 70 POINTS AND 79 POINTS: $"
STR4 DB "NUMBER OF SCORE BETWEEN 60 POINTS AND 69 POINTS: $"
STR5 DB "NUMBER OF SCORE UNDER 60 POINTS: $"
SHUJU ENDS

CODE SEGMENT
    ASSUME CS:CODE,DS:SHUJU
    MAIN:
        MOV AX,SHUJU
        MOV DS,AX
        MOV DX,0000H
        MOV BX,0000H
        MOV CX,40
        MOV SI,OFFSET DATA
        MOV DI,OFFSET BUFFER
        NINE:
            MOV AL,[SI]
            CMP AL,90
            JC EIGHT
            INC DH
            JMP STOR
        EIGHT:
            CMP AL,80
            JC SEVEN
            INC DL
            JMP STOR
        SEVEN:
            CMP AL,70
            JC SIX
            INC BH
            JMP STOR
        SIX:
            CMP AL,60
            JC FIVE
            INC BL
            JMP STOR
        FIVE:
            INC BP
        STOR:
            INC SI
        LOOP NINE

        MOV [DI],DH
        MOV [DI+1],DL
        MOV [DI+2],BH
        MOV [DI+3],BL
        MOV [DI+4],BP
        
        LEA DX,STR0 
        MOV AH,09H
        INT 21H
        MOV CX,40
        LEA SI,DATA
    SHOW: 
        MOV AX,0
        MOV AL,[SI]
        CALL PRINTF
        CALL SPACE
        INC SI
    LOOP SHOW 
        CALL CRLF
        LEA DX,STR1
        MOV AH,09H
        INT 21H
        MOV AX,0
        MOV AL,[DI]
        CALL PRINTF
        CALL CRLF
        LEA DX,STR2
        MOV AH,09H
        INT 21H
        MOV AX,0
        MOV AL,[DI+1]
        CALL PRINTF
        CALL CRLF
        LEA DX,STR3
        MOV AH,09H
        INT 21H
        MOV AX,0
        MOV AL,[DI+2]
        CALL PRINTF
        CALL CRLF
        LEA DX,STR4
        MOV AH,09H
        INT 21H
        MOV AX,0
        MOV AL,[DI+3]
        CALL PRINTF
        CALL CRLF
        LEA DX,STR5
        MOV AH,09H
        INT 21H
        MOV AX,0
        MOV AL,[DI+4]
        CALL PRINTF
        CALL CRLF
        MOV AX,4C00H
        INT 21H

    PRINTF PROC NEAR
        PUSH CX
        PUSH BX
        PUSH DX
        MOV CX,0
        MOV BX,10
    DISP1:
        MOV DX,0
        DIV BX
        PUSH DX
        INC CX
        OR AX,AX
        JNE DISP1
    DISP2:
        MOV AH,2
        POP  DX 
        ADD  DL,30H
        INT 21H
        LOOP DISP2
        ;CALL CRLF
        POP DX
        POP BX
        POP CX
        RET
    PRINTF ENDP
    CRLF PROC NEAR
        PUSH AX
        PUSH DX
        MOV DL,0AH
        MOV AH,2H
        INT 21H
        MOV DL,0DH
        MOV AH,2H
        INT 21H
        POP DX
        POP AX
        RET
    CRLF ENDP

    SPACE PROC NEAR
        PUSH AX
        PUSH DX
        MOV DL,20H
        MOV AH,2H
        INT 21H
        POP DX
        POP AX
        RET
    SPACE ENDP
    CODE ENDS
END MAIN

实验结果:
在这里插入图片描述

实验3

实验代码:

ASSUME CS:CODE,DS:DATA

DATA SEGMENT
  STRING0 DB 'PLEASE INPUT A NUMBER: $'
  STRING1 DB 'IT IS ODD $'
  STRING2 DB 'IT IS EVEN $'
  STRING3 DB 'INLEGAL CHARACTER!$'
DATA ENDS
 
CODE SEGMENT
START:
    MOV AX,DATA
    MOV DS,AX
    LEA DX,STRING0 
    MOV AH,09H
    INT 21H
    MOV CX,10
INPUT:
    MOV AH,01H
    INT 21H
    CMP AL,039H
    JA INLEGAL
    CMP AL,0DH 
    JE OUTSIDE
    MOV BL,AL
LOOP INPUT
INLEGAL:   
    CALL CRLF
    LEA DX,STRING3 
    MOV AH,09H
    INT 21H
    JMP TAIL
OUTSIDE:
    CALL CRLF
    AND BL,01H
    CMP BL,1
    JNE EVEN
ODD:
    LEA DX,STRING1
    MOV AH,09H
    INT 21H
    JMP TAIL
EVEN:
    LEA DX,STRING2
    MOV AH,09H
    INT 21H

TAIL:
    MOV AX,4C00H
    INT 21H

    CRLF PROC NEAR
        PUSH AX
        PUSH DX
        MOV DL,0AH
        MOV AH,2H
        INT 21H
        MOV DL,0DH
        MOV AH,2H
        INT 21H
        POP DX
        POP AX
        RET
    CRLF ENDP

CODE ENDS
END START

实验结果:
在这里插入图片描述
在这里插入图片描述

实验4

实验代码:

DATA SEGMENT 
    STRING1 DB 'PLEASE INPUT A STRING: $'
    STRING2 DB 'THE NUMBER OF CHAR A: $'
DATA ENDS
 
CODE SEGMENT
    MAIN PROC FAR
    ASSUME CS:CODE,DS:DATA
    START:
        MOV AX,DATA
        MOV DS,AX
        MOV CX,16
        LEA DX,STRING1 
        MOV AH,09H
        INT 21H
        MOV DX,0   
    WRITE:
        MOV AH,1H
        INT 21H
        CMP AL,0DH 
        JE PRINT
        CMP AL,41H 
        JNE NEXT
        INC DL    
    NEXT:
    LOOP WRITE
     
    PRINT:
        CALL CRLF
        PUSH DX
        LEA DX,STRING2
        MOV AH,09H
        INT 21H
        POP DX
        ADD DL,30H
        MOV AH,02H
        INT 21H

        MOV AX,4C00H
        INT 21H
    MAIN ENDP

    CRLF PROC NEAR
        PUSH DX
        MOV DL,0AH
        MOV AH,2H
        INT 21H
        MOV DL,0DH
        MOV AH,2H
        INT 21H
        POP DX
        RET
    CRLF ENDP
CODE ENDS
END START

实验结果:
在这里插入图片描述

实验5

实验代码:

DATA SEGMENT 
    BUF1 DB 1,2,3,5,7,9
    BUF2 DB 0,2,4,6,8
    BUF3 DB 32 DUP(204)
    N1     DB 6
    N2     DB 5
DATA ENDS

CODE SEGMENT
    ASSUME CS:CODE,DS:DATE
    START:
        MOV AX,DATA
        MOV DS,AX
        LEA SI,BUF1
        LEA DI,BUF2
        LEA BX,BUF3
        MOV AX,0
        MOV CX,0
        MOV DX,0
        MOV AH,N1
        MOV AL,N2
        MOV CL,N1
        ADD CL,N2
        MOV DX,WORD PTR N2 
        DEC DX
        MOV DH,0
        ADD DL,AH

        MOV AX,WORD PTR N1 
        DEC AX
        MOV AH,0
    WHILE:
        CMP SI,AX
        JA B2
        CMP DI,DX
        JA B1
        PUSH DX
        MOV DX,[DI]
       CMP [SI],DL
        POP DX
        JA B2       
        JB B1         
        PUSH DX
        PUSH AX
        MOV DX,[SI]
        MOV [BX],DL 
        ADD DL,30H
        MOV AH,2H
        INT 21H
        POP AX
        POP DX
        INC SI
        INC DI
        INC BX
        DEC CX
        JMP TAIL
    B2:    
        PUSH DX
        PUSH AX
        MOV DX,[DI]
        MOV [BX],DL
        ADD DL,30H
        MOV AH,2H
        INT 21H
        POP AX
        POP DX
        INC BX
        INC DI
        JMP TAIL
    B1:
        PUSH DX
        PUSH AX
        MOV DX,[SI]
        MOV [BX],DL
        ADD DL,30H 
        MOV AH,2H
        INT 21H
        POP AX
        POP DX
        INC BX
        INC SI
    TAIL:
    LOOP WHILE
        MOV AX,4C00H
        INT 21H

    CRLF PROC NEAR
        PUSH DX
        MOV DL,0AH
        MOV AH,2H
        INT 21H
        MOV DL,0DH
        MOV AH,2H
        INT 21H
        POP DX
        RET

CODE ENDS
END START

实验结果:
在这里插入图片描述

四、实验总结

  • 顺序结构程序:是最简单的,也是最基本的程序结构形式,最大特点就是程序运行时从开始到结尾一直是按照编写指令的顺序执行,且每条指令仅执行一次,没有分支和循环,具有顺序结构的程序或者程序段,成为顺序程序。
  • 分支结构程序:利用条件转移指令或跳转表,使程序执行完某条指令后,根据指令执行后状态标志的情况选择要执行哪个程序段。分支结构程序的指令执行顺序与指令的存储顺序不一致,转移指令JMP和Jcc可以实现分支结构。
  • 循环结构程序:当程序处理的问题需要包含多次重复执行某些相同的操作时,在程序中可以使用循环结构来实现,即用同一组指令,每次替换不同的数据,反复执行这一组指令。使用循环结构,可以缩短程序代码,提高编程效率。
    设计循环结构程序时,要注意以下问题:
    • 选用计数循环还是条件循环,采用直到型循环结构还是当型循环结构;
    • 可以用循环次数、计数器、标志位、变量值等多种方式来作为循环的控制条件,进行选择时,要综合考虑循环执行的条件和循环退出的条件;
    • 注意不要把初始化部分放到循环体中,循环体中要有能改变循环条件的语句。
  • 子程序设计:为了避免重复编写程序,节省内存空间,把该程序段独立出来,以供其他程序调用,这段程序称为“子程序”或“过程”。
    子程序是可供其他程序调用的具体特定功能的程序段。
    调用子程序的程序体,称为“主程序”或“调用程序”。
    采用子程序进行程序设计的注意点:
    • 现场保护和恢复;
      所谓“现场保护”是指子程序运行时,对可能破坏的主程序用到的寄存器、堆栈、标志位、内存数据值进行的保护。
      所谓“现场恢复”指由子程序结束运行返回主程序时,对被保护的寄存器、堆栈、标志位、内存数据值的恢复。常利用堆栈和空闲的存储区实现现场保护和现场恢复。
    • 子程序嵌套;
      一个程序可以调用某个子程序,该子程序可以调用其他子程序,这就形成子程序嵌套。
      子程序嵌套调用的层次不受限制,其嵌套层数称为“嵌套深度”。
      由于子程序中使用堆栈来保护断点,堆栈操作的“先进后出”特性能自动保证各个层次子程序断点的正确入栈和返回。
      在嵌套子程序设计中,应注意寄存器的保护和恢复,避免各层子程序之间寄存器发生冲突。特别是在子程序中使用PUSH、POP指令时,要格外小心,以免造成子程序无法正确返回。
    • 参数传递。
      主程序在调用子程序时,经常需要向子程序传递一些参数或控制信息,子程序执行完成后,也常常需要把运行的结果返回给调用程序,这种调用程序和子程序之间的信息传递,称为“参数传递”。
      参数传递的主要方法有:寄存器传递、内存变量传递和堆栈传递。
      传递的内容如果是数据本身,称为“值传递”,如果是数据所在单元的地址,称为“地址传递”。
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐