微机原理上机实验 - 汇编

        这是《微机原理》这门课(2012下学期)的上机实验题目(2012.11.23完成)。初学汇编,对自己要求严格,尽量实现模块化,使程序简单易读。仅供初学者借鉴。

程序设计综合练习

一、    实验目的

       1.增强和提高汇编语言程序设计的能力,掌握模块化程序设计的方法.

       2.熟练掌握DOS常用功能的调用方法.

二、    实验仪器

       586微机   一台

三、    实验内容

        编写如下程序,并在机器上调试成功。程序采用菜单式选择,可以接收用户从键盘输入的五个命令(1-5),各命令功能分别为:

       (1) 按下“1”键,完成字符串小写字母变成大写字母。

        用户输入一由英文大小写字母或数字0-9组成的字符串(以回车结束),程序逐个检查字符串中各字符,将原串中小写字母变成大写字母,其他字符不变,并在屏幕上显示。用户按任一键,重做,按ESC键,返回主菜单。   

       (2) 按下“2”键,完成找最大值(二选一)。

       a.接收用户输入的可显示字符串(以回车结束),程序将其中ASCII码值最大的字符显示出来;

    b.接收用户输入若干个无符号8位数(以空格或逗号为分隔符,以回车结束),程序将其中最大的数显示出来。用户按任一键,重做,按ESC键,返回主菜单。

       (3) 按下“3”键,完成排序(二选一)。

       a.接收用户输入的可显示字符串,以回车结束。程序按ASCII码值大小由大到小排序并输出显示;

       b.接收用户输入若干个有符号8位数(以空格或逗号为分隔符,以回车结束),程序将其中最大的数显示出来。用户按任一键,重做,按ESC键,返回主菜单。

       (4) 按下“4”键,显示时间。

       首先提示用户对时,即用户输入时、分、秒(以空格或逗号为分隔符,以回车结束),然后,在屏幕上不断显示时间,格式为:

                           XX(时): XX(分): XX(秒)

       最好定点显示。用户按任一键,重新对时,按ESC键,返回主菜单。

       (5) 按下“5”键,结束程序运行,返回系统提示符。

四、    源程序及流程

1.      流程图

 

       系统流程图如下图1:

  微机原理上机实验 - 汇编_第1张图片

 

 图1 多功能程序流程图

       运行部分结果如下:

 

图2 程序运行主菜单

微机原理上机实验 - 汇编_第2张图片

图3 程序子菜单1(小写转大写)

 微机原理上机实验 - 汇编_第3张图片

图4 程序子菜单4(时间显示)

微机原理上机实验 - 汇编_第4张图片 

图5 程序子菜单4(时间设置)

 

 

2.      源程序

 

;宏定义

;-------------------------------------------------------

;-------显示字符串-------

;-------------------------------------------------------

DISPL MACRO STR        ;Function to display strings

      PUSH DX

      PUSH AX

      LEA DX,STR

      MOV AH,09H

      INT 21H

      POP AX

      POP DX

ENDM

;-------------------------------------------------------

;-------判断用户是否选择继续-------

;-------------------------------------------------------

ISCONTINUE  MACRO L    ;Macro to judge whether to continue, L is a mark

      DISPS 15,10,SMENU

      MOV   AH,08H

      INT   21H

      CMP   AL,1BH

      JNE   L          ;若用JE会导致编译,跳不了那么远

      JMP   MAIN

ENDM

;-------------------------------------------------------

;-----设置光标宏----

;-------------------------------------------------------

CURSOR MACRO CURX,CURY

  PUSH AX

  PUSH BX

  PUSH DX         ;DX必须保护,始终指向输入缓冲区

        MOV AH,02H

        MOV DH,CURX

         MOV DL,CURY

         MOV BH,0

        INT 10H

  POP DX

  POP BX

  POP AX

ENDM

 

;-------------------------------------------------------

;-----定位字符串显示宏------

;-------------------------------------------------------

DISPS  MACRO X,Y,STR ;将STR的内容显示到X,Y的位置

  PUSH AX

  PUSH BX

  PUSH DX

        MOV AH,02H

        MOV BH,00H  ;显示页码,第0页

        MOV DH,X    ;行(X坐标)

        MOV DL,Y    ;列(Y坐标)

        INT 10H

  LEA DX,STR

         MOV AH,09H

        INT 21H

  POP DX

  POP BX

  POP AX

ENDM

;-------------------------------------------------------

;--------清屏加色宏------

;-------------------------------------------------------

SCROLL MACRO N,ULR,ULC,LRR,LRC,ATT

  PUSH AX

  PUSH BX

  PUSH CX

  PUSH DX

  MOV AH,06H

  MOV AL,N         ;N=上卷行数;N=0时,清窗口

  MOV CH,ULR       ;左上角行号(X)

  MOV CL,ULC       ;左上角列号(Y)

  MOV DH,LRR       ;右下角行号

  MOV DL,LRC       ;右下角列号

  MOV BH,ATT       ;卷入行属性,颜色设置

  INT 10H

  POP DX

  POP CX

  POP BX

  POP AX

ENDM

;-------------------------------------------------------

;---------子程序预处理宏---------

;-------------------------------------------------------

PREP  MACRO T           ;预处理,显示子菜单标题(T),输入提示信息等

        LEA SI,INBUF+1

  LEA DI,OUTBUF

  SCROLL 21,2,0,22,79,0FH ;清屏,内窗

  DISPS 3,20,T          ;显示子菜单标题(3行20列显示T)

       DISPS 6,2,CAPION    ;Prompt for a string to change

       DISPS 8,2,INCAP     ;Print "Your input is:"

       MOV AH,0AH

  INT 21H

       MOV CH,0

       MOV CL,[SI]       ;获取输入字符串中,字符的个数

  INC SI 

ENDM

;-------------------------------------------------------

;---------堆栈段---------

;-------------------------------------------------------

STACK SEGMENT STACK 'STACK'

      DB 100H DUP(?)

TOP LABEL WORD

STACK ENDS

;-------------------------------------------------------

;---------数据段---------

;-------------------------------------------------------

DATA  SEGMENT

BASE    DW MAIN,LTC,FMV,SORTS,STM,EXIT      ;建立跳转表

WELCM   DB 'Welcome to use this program!$'

 

MMENUI  DB '---THIS PROGRAM IS DEVELOPED BY LiuZhi!---$'

MMENUD DB '--- 2012/10/28---$'

MMENUC DB 'Please Chose An Item,And Input The Number!$'

MMENU1  DB ' 1 -Lowercase Letters To Capital Letters$'

MMENU2  DB '       2 -Find The Maximum Value$'

MMENU3  DB '               3 -Sort$'

MMENU4  DB '             4 -Set Time$'

MMENU5  DB '               5 -Exit!$'

 

 SMENU  DB 'Press Any Key To Redo,Press "ESC" To Return To Main Menu!$'

WROCAP  DB 'WRONG! You have press "  " key! Please input a number between 1 and 5!$'

CAPION  DB 'Please Input Your Strings and End With "Enter" Key!$'

INCAP   DB 'Your Input Is: $'

INBUF   DB  100

        DB  ?

        DB  100 DUP(?)

OUTCAP  DB  ' My Output Is: $'

OUTBUF  DB  100 DUP(?)

MAXCAP  DB  'The char of max ASCII is:    .$'

ERRINF  DB  'ERROR! Please check the format you input!$'

TIMESETC DB 'Now,you can set the time! $' 

TIMESETF DB 'Format:(01 25 32) or (01:25:32),and end with CR !$'

TIMESETS DB '              Succeed!            $'   

TDINV    DB '   Invalid time data! Input again!$'  

NODATCAP DB  '       You have input nothing!$'

TIME    DB  8 DUP (':'),12 DUP (' ');时间的底

 

DATA  ENDS

 

;-------------------------------------------------------

     ;-------程序开始-------

;-------------------------------------------------------

CODE  SEGMENT

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

 

START: MOV AX,DATA

       MOV DS,AX

       MOV ES,AX

       MOV AX,STACK

       MOV SS,AX

       LEA SP,TOP

       LEA DX,INBUF          ;指向输入缓冲区

       CLC   

;-----欢迎界面 及主菜单------

MAIN:   SCROLL 0,0,0,24,79,0      ;清屏

  SCROLL 25,0,0,24,79,50H   ;设置窗口颜色

  SCROLL 21,2,0,22,79,0FH   ;设置菜单颜色,黑底白字 //注意逗号应为半角字符,否则提示out of memory

       DISPS 4,20,MMENUI         ;Display the main menu

  DISPS 6,30,MMENUD

  DISPS 8,20,MMENUC

  DISPS 10,20,MMENU1

  DISPS 12,20,MMENU2

  DISPS 14,20,MMENU3

  DISPS 16,20,MMENU4

  DISPS 18,20,MMENU5

ML: CURSOR 19,1DH

        MOV AH,01H         ;Recieve the choice

        INT 21H 

        CMP AL,31H

  JL  ERROR

  CMP AL,35H

  JG  ERROR

     AND AX,00FH

  LEA BX,BASE

  SHL AL,1            ;将AL乘2,因为跳转表地址是dw类型的,

  ADD BX,AX

  JMP WORD PTR [BX]

       ;CMP AL,'1'

       ;JE  LTC            ;Choose 1,lowercase letter to capital letter

       ;CMP AL,'2'

       ;JE  FMV            ;Choose 2,find the maximum value

       ;CMP AL,'3'

       ;JE  SORTS          ;Choose 3,sort

       ;CMP AL,'4'

       ;JE  STM             ;Choose 4,show current time

       ;CMP AL,'5'

       ;JE  EXIT           ;Choose 5,exit the program

 

ERROR:  CMP AL,0DH          ;如果是回车的话,赋CR

  JE  MCR

  MOV [WROCAP+23],AL  ;Other char

  MOV [WROCAP+24],' '          

  JMP D

MCR:   MOV WORD PTR [WROCAP+23],'RC'

D:      DISPS 20,5,WROCAP       ;Show the wrong information

        JMP ML

 

LTC:   CALL  LLTOCL

       ISCONTINUE LTC

FMV:   CALL FMAXV

       ISCONTINUE FMV

SORTS: CALL SORT

       ISCONTINUE SORTS

STM:   CALL SHOWTIME

       ISCONTINUE STM

EXIT:   SCROLL 0,0,0,24,79,0   ;清屏

  MOV AH,4CH        ;Exit.

        INT 21H              

;-------------------------------------------------------

;------Process: lowercase letter to capital letter.-----

;-------------------------------------------------------                  

LLTOCL PROC             

REFLASHL:PREP MMENU1      ;显示子菜单

  CMP CL,0          ;若输入为空则跳转至REDO

  JE  REFLASHL

LL1:         MOV AL,[SI]

       CMP AL,'a'

       JB  MTOB      ;NO CHANGE

       CMP AL,'z'

       JA  MTOB

       SUB AL,20H    ;Convert

MTOB:     MOV [DI],AL

       INC SI

       INC DI

  LOOP    LL1

       MOV BYTE PTR [DI],'$'

        DISPS 10,2,OUTCAP

       DISPS 10,17,OUTBUF  

       RET

LLTOCL ENDP         

;-------------------------------------------------------

;----Process: find the maximum value.------

;-------------------------------------------------------

FMAXV  PROC       

         PUSH BX

REFLASHF:PREP MMENU2      ;显示子菜单

       CMP CL,0          ;若输入为空则跳转至REDO

  JE  REFLASHF

       MOV AL,0

FL1:    CMP AL,[SI]

       JA  NEXT

       MOV AL,[SI]

NEXT:      INC SI

      LOOP FL1

       MOV [MAXCAP+26],AL

       DISPS 10,2,MAXCAP

       POP BX

       RET         

FMAXV  ENDP  

;-------------------------------------------------------      

;-------Process: sort.----------

;-------------------------------------------------------

SORT   PROC         

       PREP MMENU3           ;显示子菜单标题(T),输入提示信息等

  DEC CX

  ADD SI,CX

  MOV BYTE PTR [SI+1],'$'

LP1:    PUSH CX

  PUSH SI

LP2:

  MOV AL,[SI]

  CMP AL,[SI-1]

  JBE NOXCHG

  XCHG AL,[SI-1]

  MOV [SI],AL

 

NOXCHG: DEC SI

   LOOP LP2

  POP SI

      POP CX

   LOOP LP1

  DISPS 10,2,OUTCAP

  DISPS 10,17,INBUF[2]         ;显示排序结果

  RET

SORT   ENDP

;-------------------------------------------------------

 ;---------Process: show current time.---------

;-------------------------------------------------------

SHOWTIME  PROC        

  SCROLL 21,2,0,22,79,0FH 清屏,内窗

  DISPS 3,20,MMENU4

  DISPS 5,25,TIMESETC

  DISPS 7,15,TIMESETF

SHOW:     MOV SI,0

       MOV BL,100

       DIV BL

      MOV AH,2CH      ;GET TIME

       INT 21H

       MOV AL,CH       ;HOUR

       CALL BCDASC     ;要转换的在AL中

       INC SI

       MOV AL,CL       ;MINUTE

       CALL BCDASC

       INC SI

       MOV AL,DH

       CALL BCDASC      ;要转换的在AL中

 

       MOV BP,OFFSET TIME   ;使用int 10H的13H号功能,在Teletype模式下显示字符串(BP为地址)

       MOV DX,0A22H         ;DX为行列(DH,DL)

       MOV CX,8             ;CX为显示字符串长度

       MOV BX,004EH         ;BH:页码,BL:属性

       MOV AX,1301H         ;AL:显示输出方式,1—字符串中只含显示字符,显示后,光标位置改变

       INT 10H             

       MOV AH,02H           ;设置光标位置

       MOV DX,0A22H

       MOV BH,0

       INT 10H

       MOV BX,0018H          ;延时用(外层),若不延时,光标会在时间左右来回跑!

RE:    MOV CX,0FFFFH

REA:   LOOP REA

       DEC BX

       JNZ RE                ;

       MOV AH,01H            ;检测是否有字符输入,ZF=1:无

       INT 16H

  JE SHOW

       CALL SETTIME          ;设置时间子程序

       RET

SHOWTIME  ENDP

;-------------------------------------------------------

 ;-------------设置时间子程序----------

;-------------------------------------------------------

SETTIME PROC               

  PUSH DX

  MOV AH, 0AH         ; 输入时间串

  LEA DX, INBUF

  INT 21H                        

  CMP INBUF[1],0

      JE  NODAT

  MOV BL, 10

  MOV AL, INBUF + 2

  SUB AL, '0'

  MUL BL

  ADD AL, INBUF + 3

  SUB AL, '0'

  CMP AL, 0

  JB INVALID

  CMP AL, 24

  JAE INVALID          ; 判断 时 有效性

  MOV CH, AL

  MOV AL, INBUF + 5

  SUB AL, '0'

  MUL BL

  ADD AL, INBUF + 6

  SUB AL, '0'

  CMP AL, 0

  JB INVALID

  CMP AL, 60

  JAE INVALID          ; 判断 分 有效性

  MOV CL, AL

  MOV AL, INBUF + 8

  SUB AL, '0'

  MUL BL

  ADD AL, INBUF + 9

  SUB AL, '0'

  CMP AL, 0

  JB INVALID

  CMP AL, 60

  JAE INVALID          ; 判断 秒 有效性

  MOV DH, AL

  MOV DL, 0

  MOV AH, 2DH

  INT 21H              ; 置系统时间

  DISPS 12,20,TIMESETS    ;设置成功

  JMP RETURN

NODAT:  DISPS 12,20,NODATCAP

  JMP RETURN

INVALID:DISPS 12,20,TDINV       ;时间数据无效    

RETURN:  POP DX

  RET

SETTIME ENDP

;-------------------------------------------------------

;------Process:时间数值转换成ASCII码字符子程序,要转换的在AL中,调用前赋好值------

;-------------------------------------------------------

BCDASC PROC NEAR   

       PUSH BX

       CBW

       MOV BL,10

       DIV BL

       ADD AL,30H

       MOV TIME[SI],AL

       INC SI

       ADD AH,30H

       MOV TIME[SI],AH

       INC SI

       POP BX

       RET

BCDASC ENDP

;------结束!------

CODE  ENDS

END   START

 

五、    实验体会

1.        要熟练掌握8086汇编指令,包括寻址方式,指令格式等等;

2.        在编程实现阶段,汇编时提示跳转不到的问题,根据错误提示可知是条件转移指令的问题,因为它所跳的范围在-127~+128字节,因而改用了“跳转表”来实现主程序至子程序的跳转;

3.        INT 21H中断提供的功能有限,为使程序界面友好美观,操作简便,在实现时调用了INT 10H中断,程序中使用的中断见附录;

4.        编写汇编程序,给人的感觉是不断地把数据从一个地方搬到另一个地方,再加上一些对数据的处理,所以,画出流程图再编程,可加快速度,另外最好有个汇编指令详表,遇到不清楚的可随手查,如此,可加深记忆与加快开发的速度。

 

附录

程序中用到的INT 10H 中断:

1. 02H

       功能:用文本坐标下设置光标位置

       入口参数:AH=02H

            BH=显示页码

                   DH=行(Y坐标)

                   DL=列(X坐标)

       出口参数: 无

 

2. 06H和07H

       功能:初始化屏幕或滚屏

       入口参数:AH=06H—向上滚屏,07H—向下滚屏

                  AL=滚动行数(0—清窗口)

                  BH=空白区域的缺省属性

                 (CH、CL)=窗口的左上角位置(Y坐标,X坐标)

                 (DH、DL)=窗口的右下角位置(Y坐标,X坐标)

       出口参数: 无

 

3. 13H

       功能:在Teletype模式下显示字符串

       入口参数:AH=13H

            BH=页码

            BL=属性(若AL=00H或01H)

            CX=显示字符串长度

           (DH、DL)=坐标(行、列)

            ES:BP=显示字符串的地址 AL= 显示输出方式

       0—字符串中只含显示字符,其显示属性在BL中。显示后,光标位置不变

       1—字符串中只含显示字符,其显示属性在BL中。显示后,光标位置改变

       2—字符串中含显示字符和显示属性。显示后,光标位置不变

       3—字符串中含显示字符和显示属性。显示后,光标位置改变

       出口参数: 无。

 

你可能感兴趣的:(大作业&实验,汇编语言,设计,界面,编程,微机原理)