汇编8086 打字游戏大作业

; multi-segment executable file template.
SCROLL    MACRO     N,ULR,ULC,LRR,LRC,ATT	;宏定义
          MOV       AH,6				;清屏或上卷
          MOV       AL,N		;N=上卷行数;N=0时,整个窗口空白
          MOV       CH,ULR		;左上角行号
          MOV       CL,ULC		;左上角列号
          MOV       DH,LRR		;右下角行号
          MOV       DL,LRC		;右下角列号
          MOV       BH,ATT		;卷入行属性
          INT       10H
          ENDM  
CURSE     MACRO     CURY,CURX    
          MOV       AH,2		     	;置光标位置
          MOV       DH,CURY			;行号
          MOV       DL,CURX			;列号
          MOV       BH,0			;当前页
          INT       10H
ENDM

PRINT macro MSG
    curse 22,3
    lea dx,MSG
    mov ah,09h
    int 21h
    curse 22,3
endm
data segment
    ; add your data here!
  menu db 0ah,0dh,"           The Author : LWG",0ah,0dh 
  db "------------Welcome to Typing Practice System!------------",0ah,0dh
         db 0ah,0dh,"           The left side of the system is the practice screen."
         db 0ah,0dh,"           The upper right corner of the system is grades."
         db 0ah,0dh,"           The lower right corner of the system is the practice time",0ah,0dh 
         
         db 0ah,0dh,"           Enter a number to select a function."
         db 0ah,0dh,"                Press enter to start the practice."
         db 0ah,0dh,"                      1:Start practicing"
         db 0ah,0dh,"                      2:Quit practice"
         db 0ah,0dh,"                Press ESC at any time to exit the exercise.",0ah,0dh
         db 0ah,0dh,"           Tip: The input number must be 1 or 2."
         db 0ah,0dh,"                Please input your select:$"
   msg1   db "today is a good day aaaaaaaaaaa$"
    msg2  db "i hope all have a good day aaaa$"
    msg3  db "it is a good day to stduy hardl$"
    msg4  db "china is a country in th worldd$"
    msg5  db "i like to play with my friend a$"
    msg6  db "we can get a good grade aaaaaaa$"
    msg7  db "the summer is coming aaaaaaaaaa$"
    msg8  db "it is a good job for We student$"
    msg9  db "teacher is working hard for usa$"
    msg10 db "i never give up to work suceess$"
    
    cornum dw 0 
    time1 db 'START TIME: min:',0,0,'sec:',0,0,'msec:',0,0,'$' 
    time2 db 'THIS  TIME: min:',0,0,'sec:',0,0,'msec:',0,0,'$' 
    time3 db "min  ","sec  ","mec","$"
    time4 db 20h,0,0,20h,20h,20h,0,0,20h,20h,20h,0,0,20h,10,dup(0),'$' 
    ;         2,3           7,8    12,13                                                
    table dw msg1,msg2,msg3,msg4,msg5,msg6,msg7,msg8,msg9,msg10
    pkey1 db "For this exercise, $"
    pkey2 db "Your score is:$"                
    pkey3 db "/310$"
    pkey4 db "Time for this exercise:$"
    pkey5 db "The practice is over, thank you for using!!!!!!$"
    CH1 DB 0DH,0AH,"$"
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:
; set segment registers:
    mov ax, data
    mov ds, ax
    mov es, ax

    ; add your code here
  ;PRESS Esc TO EXIT         			; 清屏或上卷宏定义



    restart:
     call begin
     mov ah,1
     int 21h
     cmp al,'1'            ;输入1跳转开始练习
     jz next1
     cmp al,'2'            ;输入2结束运行
     jz allEnd
     jmp restart
     next1:
       call main            
     allEnd:
     scroll 23,1,9,23,70,10h;做一个结束屏幕        
     scroll 21,2,10,22,69,70h 
     curse 10,15
     lea dx,pkey5
     mov ah,9
     int 21h
    
    mov ax, 4c00h ; exit to operating system.
    int 21h    
ends  
;打字子程序

 ;开始界面子程序
    begin proc 
        scroll 23,1,9,23,70,10h        ;开始界面
        scroll 21,2,10,22,69,70h
        curse 5,11
        lea dx,menu                    ;打印菜单
        mov ah,9
        int 21h      
        ret
    begin endp 


MAIN      PROC      
         SCROLL    0,0,0,24,79,02		;清屏
         scroll 24,1,2,23,35,10h    ;开外窗口,蓝色底
        ;上卷行数,左上角行号,左上角列号,右下角行号,右下角列好
        scroll 21,2,3,22,34,70h    ;开内窗口,灰底黑字
        scroll 11,1,40,11,74,10h   ;时间窗口
        scroll 9,2,41,10,73,70h    
        scroll 11,13,40,23,74,10h  ;成绩窗口
        scroll 9,14,41,22,73,70h   
        CURSE    21,3 ;置光标于20行3列
         ;SCROLL    13,7,19,19,51,50H		;开外窗口,品红底
         ;SCROLL    11,8,20,18,50,2FH	;开内窗口,绿底白字
         ; CURSE     18,20			;置光标于18行20列
        mov cx,9;10次机会
        lea di,table;将10个句子的首地址作为一个数组存放,而现在di则是存放该数组的首地址
         
GET1:     
        push cx ;保存循环数据              
        mov bp,[di];取出句子,准备打印
        mov si,0
        print bp,22,3               ;打印源文本
        MOV       CX,31			;置一行字符数
GET2:     
        mov ah,0                    ;等待输入
        int 16h 
          PUSH      AX
          push dX
          mov dl,7                  ;?ìá?
          mov ah,02h
          int 21h
          pop dX     
          POP       AX
        cmp al,27                    ;是否为ESC键?
        JZ        EXIT				;是,退出    
        push CX;保护字符个数
        cmp al,ds:[bp+si]           ;比较输入字符与源字符
        jz correct                  ;正确跳转,错误顺序执行
        
        CMP       AL,0DH ;检测是否为换行
        JZ        HUANHANG;跳过本行输出    
        ;dec cornum                  ;分数-1
        mov al,ds:[bp+si]            ;取出该数组的首地址的偏移量
        mov ah,09h                  
        mov bl,74h                  ;错误输出红色字体
        mov cx,1
        mov bh,0
        int 10h
        jmp next2 
     
        
    correct:
        inc cornum                  ;分数+1              
        mov ah,09h                  ;显示输入的字符
        mov bl,7eh                  ;正确字符
        mov cx,1
        mov bh,0h
        int 10h    
        
    next2:    
        mov ah,02h                  ;移动光标
        inc dx
        inc si
        pop cx
        int 10h
        loop get2 
        
        HUANHANG: 
       ; 
        ;JZ        HUANHANG    
     ;   MOV       AH,0EH			;显示输入的字符
      ;  INT       10H  
        
       ; LOOP      GET2;循环次数
        ;HUANHANG:
        ;scroll 1,2,3,22,34,70h;换行上卷 
        CURSE    21,3 ;光标重置 
        call timeTrans1  ;展现开始时间
        call timeTrans2  ;展现结束时间
        CURSE    21,3;给光标充值  

        scroll 1,2,3,22,34,70h     ;上卷一行   
        add di,2;将下一句句子提上来                      
        pop cx ;字符出栈   
        call Score;调用积分函数
        loop get1 ;继续循环  
        
        
EXIT:
        pop cx                  ;将无关数据弹出  
        ret
MAIN      ENDP

   
Score proc near
        curse 5,42
        lea dx,pkey1
        mov ah,9
        int 21h
        curse 6,42
        lea dx,pkey2
        mov ah,9
        int 21h              
        
        mov ah,2
        mov dl,'0'
        int 21h
        mov ax,cornum              ;输出分数
        cmp ax,0
        jz  out3
        mov dx,0
        mov cx,0                   ;计数器
        jmp out1             
        
     get3:
        cmp ax,0
        jz  out2
     out1:   
        mov bl,10
        div bl
       
        add ah,'0'
        mov dl,ah
        push dx
        mov ah,0
        inc cx
        jmp get3 
        
     out2:       
        pop dx
        mov ah,2
        int 21h
        loop out2
       
     out3:
        lea dx,pkey3
        mov ah,9
        int 21h
                    
Score endp     
          
trans_D proc near 
    mov ah,0
    mov bh,0Ah
    div bh
    shl al,4
    add al,ah
    ret
trans_D endp

timeTrans1 proc near;将十六进制的时间转换成为10进制时间
    
    push ax
    push bx
    push cx
    push dx
    
    mov ah,2ch   ;取系统时间其中时、分、秒、毫秒分别对应dh dl ch cl
    int 21h
    
    xor ax,ax;清零
    mov bl,dh ;把ch赋值给bl
             
    mov ax,cx ;处理个位
    call trans_D
    mov cl,al
    
    mov ax,bx
    call trans_D ;处理十位
    mov bl,al
    
    mov ax,dx ;处理百位
    call trans_D
    mov dl,al
             
    mov ch,cl     ;把例如0016这样的数变成0106方便输出
    and cl,0Fh
    shr ch,4 
    
    add cx,3030h
    mov time1[16],ch ;将分钟的数值移入到缓冲区
    mov time1[17],cl
    
    
    mov bh,bl
    and bl,0Fh
    shr bh,4 
    
    add bx,3030h 
    mov time1[22],bh ;把秒的数值移入到缓冲区
    mov time1[23],bl
    
    mov dh,dl
    and dl,0Fh
    shr dh,4    
    
    add dx,3030h 
    mov time1[29],dh   ;把毫秒的数值移入到缓冲区
    mov time1[30],dl
    
    CURSE    15,41     ;重置光标
    
    lea dx,time1
    mov ah, 9
    int 21h 
    
    pop dx       ;清空数据据,开始退栈
    pop cx
    pop bx
    pop ax
    
    ret
timeTrans1 endp

timeTrans2 proc near    
    
    push ax
    push bx       ;进栈
    push cx
    push dx
    
    mov ah,2ch
    int 21h
    
    xor ax,ax
    mov bl,dh
             
    mov ax,cx
    call trans_D
    mov cl,al
    
    mov ax,bx
    call trans_D
    mov bl,al
    
    mov ax,dx
    call trans_D
    mov dl,al
             
    mov ch,cl
    and cl,0Fh
    shr ch,4 
    
    add cx,3030h
    mov time2[16],ch ;min
    mov time2[17],cl
    
    
    mov bh,bl
    and bl,0Fh
    shr bh,4 
    
    add bx,3030h 
    mov time2[22],bh ;sec
    mov time2[23],bl
    
    mov dh,dl
    and dl,0Fh
    shr dh,4    
    
    add dx,3030h 
    mov time2[29],dh ;mec
    mov time2[30],dl
    
    CURSE    17,41
    
    lea dx,time2
    mov ah, 9
    int 21h  
    CURSE    19,41
    lea dx,time3
    mov ah,9
    int 21h 
    
    CURSE    21,41 
     ;         2,3           7,8    12,13     
    mov dh,time1[16]
    mov dl,time1[17]
    mov ah,time2[16]
    mov time4[2],ah  
    mov al,time2[17]
    mov time4[3],al 
    sub time4[2],dh
    sbb time4[3],dl
    add time4[2],30h
    add time4[3],30h    
    
    mov dh,time1[22]
    mov dl,time1[23]
    
    mov al,time2[22]
    mov time4[7],al;sec,7,8留下作为空格  
                      
    mov al,time2[23]
    mov time4[8],al 
    sub time4[7],dh
    sbb time4[8],dl
    add time4[7],30h
    add time4[8],30h   
    
    mov dh,time1[29]
    mov dl,time1[30]
    
    mov al,time2[29]
    mov time4[12],al;sec,3,4留下作为空格  
    cmp time4[12],dh   
    mov al,time2[30]
    mov time4[13],al 
    jb a                  
   
   
    jmp done
    a:
    sub time4[8],1
    add time4[12],10
  
    done:
    cmp time4[13],dl ;将结束时间的msec与开始时间做对比
    jb flag
    jmp today
    flag:
    sub time4[12],1  ;如果结束时间个位的msec比开始时间的小,向十位借位
    add time4[13],10
    today:
    sbb time4[12],dh  ;如果结束时间十位的msec比开始时间的小,向十位借位
    sbb time4[13],dl 
    add time4[12],30h
    add time4[13],30h
    lea dx,time4+1
    mov ah,9
    int 21h  
       
    
    pop dx
    pop cx
    pop bx
    pop ax
    
    ret
    
timeTrans2 endp        
    
    ; wait for any key....    
  
    mov ah, 1
    int 21h
    
    mov ax, 4c00h ; exit to operating system.
    int 21h    
ends

end start ; set entry point and stop the assembler.
.

 总结输入输出程序及菜单的编写方法。 

汇编8086输入输出程序及菜单的编写方法可以总结如下:

1. 输入输出程序的编写方法:

1.1. 调用INT 21h中断实现输入输出操作。

1.2. 使用AH寄存器指定要进行的操作,比如01h表示读取键盘输入,09h表示输出字符串等。

1.3. 使用DX寄存器指定输入输出缓冲区的地址。

1.4. 使用INT 21h中断执行输入输出操作。

2. 菜单的编写方法:

2.1. 使用循环结构实现菜单的显示和输入选择。

2.2. 使用ASCII码实现菜单的显示。

2.3. 使用INT 21h中断实现键盘输入的获取。

2.4. 使用条件跳转语句根据用户输入执行相应的操作。

另外我觉得需要注意的是在编写菜单程序时,重要的是要处理错误和无效输入。可以使用条件跳转指令检查用户的输入是否有效,并在无效输入时显示错误消息。

3) 总结常用系统调用的功能及调用方法。

我在大作业代码中常用的系统调用是INT 16H和INT 10H,以及INT 21H。下面让我简单谈一下:
INT 10H:

01H

功能:设置光标形状

入口参数: AH=01H

                   CH低四位=光标的起始行

                   CL低四位=光标的终止行

        出口参数: 无

02H

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

入口参数:AH=02H

             BH=显示页码

              DH=行(Y坐标)

              DL=列(X坐标)

出口参数: 无

03H

功能:在文本坐标下,读取光标各种信息

入口参数:AH=03H

             BH=显示页码

        出口参数:CH=光标的起始行

             CL=光标的终止行

             DH=行(Y坐标)

             DL=列(X坐标)

04H

功能:获取当前状态和光笔位置

入口参数:AH=04H

出口参数:AH=00h—光笔未按下/未触发,01h—光笔已按下/已触发

             BX=象素列(图形X坐标)

             CH=象素行(图形Y坐标,显示模式:04H~06H)

                  CX=象素行(图形Y坐标,显示模式:0DH~10H)

             DH=字符行(文本Y坐标)

            DL=字符列(文本X坐标)

05H

功能:设置显示页,即选择活动的显示页

入口参数:AH=05H

                  AL=显示页

       对于CGA、EGA、MCGA和VGA,其显示页如下表所列:

模式   页数        显示器类型

00H    01H 0~7     CGA、EGA、MCGA、VGA

02H    03H 0~3     CGA

02H    03H 0~7     EGA、MCGA、VGA

07H     0~7        EGA、VGA

0DH    0~7         EGA、VGA

0EH    0~3         EGA、VGA

0FH    0~1         EGA、VGA

10H    0~1         EGA、VGA

06H和07H

功能:初始化屏幕或滚屏

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

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

                  BH=空白区域的缺省属性

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

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

出口参数: 无

08H

功能:读光标处的字符及其属性

入口参数:AH=08H

             BH=显示页码

出口参数:AH=属性

             AL=字符

09H

功能:在当前光标处按指定属性显示字符

入口参数:AH=09H

             AL=字符

                  BH=显示页码

                  BL=属性(文本模式)或颜色(图形模式)

                  CX=重复输出字符的次数

出口参数:无

0AH

功能:在当前光标处按原有属性显示字符

入口参数:AH=0AH

            AL=字符

             BH=显示页码

             BL=颜色(图形模式,仅适用于PCjr)

            CX=重复输出字符的次数

出口参数:无

INT 16H

键盘I/O中断调用有三个功能,功能号为0, 1, 2,且必须把功能号放在AH中。

(1)0号功能调用 格式:MOV AH, 0

INT 16H

功能:从键盘读入字符送AL寄存器。执行时,等待键盘输入,一旦输入,字符的ASCII码放入AL中。若AL=0,则AH为输入的扩展码。

(2)1号功能调用

格式:MOV AH, 01H

INT 16H

功能:用来查询键盘缓冲区,对键盘扫描但不等待,并设置ZF标志。若有按键操作(即键盘缓冲区不空),则ZF=0,AL中存放的是输入的ASCII码,AH中存放输入字符的扩展码。若无键按下,则标志位ZF=1。

(3)2号功能调用

格式: MOV AH, 02H

INT 16H

功能:检查键盘上各特殊功能键的状态。执行后,各种特殊功能键的状态放入AL寄存器中,

这个状态字记录在内存0040H:0017H单元中,若对应位为“1”,表示该键状态为“ON”,处于按下状态;若对应位为“0”,表示该键状态为“OFF”,处于断开状态。

而对于INT 21H来说

INT 21h是一个通用的系统调用,用于执行各种输入输出和其他类似任务。它的功能包括:

- 读取字符

- 读取字符串

- 显示字符

- 显示字符串

- 读取磁盘扇区

- 写入磁盘扇区

- 等等

INT 21h的调用方法如下:

- 将所需的系统调用功能号放入AH寄存器中。

- 将需要传递给系统调用的参数放入其他寄存器中,例如DS:DX指向字符串缓冲区,CX指定字符串长度等。

- 调用INT 21h中断。

代码总结:

1.时间中断没有设置好

2.程序IO速度没有提高

等小编有空了再完善吧,要期末考试了

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值