当前位置: 代码迷 >> 汇编语言 >> 汇编打字游戏。出现了一点小bug!该如何解决
  详细解决方案

汇编打字游戏。出现了一点小bug!该如何解决

热度:4056   发布时间:2013-02-26 00:00:00.0
汇编打字游戏。。。。。出现了一点小bug!!!!!
Assembly code
Init_game macro op1,op2,op3,op4,op5,op6   mov cx,00h   mov dh,op1   mov dl,op2 op6:mov ah,02h        ;设置光标位置 mov bh,00h   int 10h  push cx  mov ah,0ah           ;重复显示相同字符 mov al,op3           ;要显示的字符 mov bh,00h           ;页号 mov cx,01h           ;显示的次数 int 10h  pop cx  inc cx  inc op4  cmp cx,op5  jne op6               ;不等则转移endm clear_screen macro op1,op2,op3,op4 ;清屏宏定义   mov ah,06h             mov al,00h  mov bh,07h  mov ch,op1  mov cl,op2  mov dh,op3  mov dl,op4  int 10h  mov ah,02h            ;设置光标位置 mov bh,00h            ;页号为0 mov dh,00h            ;行号为0  mov dl,00h            ;列号为0 int 10h endm menu macro op1,op2,op3 ;菜单显示宏定义   mov ah,02h            ;设置光标位置 mov bh,00h  mov dh,op1  mov dl,op2  int 10h  mov ah,09h  lea dx,op3            ;显示op3 int 21h endm data segment  ZK db "WELCOME TO PLAY$"  no db "date:2003/6/24$" meg db "press Enter key to continue.......$" meg1 db "when a letter is dropping,please hit it!$" meg2 db "press space key to pause!$" meg3 db "press ESC key to return main interface!$" meg4 db "press letter 'E' to exit!$"meg5 db "press Enter key to return main interface!$" speed dw 600d letters db "jwmilzoeucgpravskntxhdyqfb"   db "iytpkwnxlsvxrmofzhgaebudjq"  db "nwimzoexrphysfqtvdcgljukda" letters_bak db "jwmilzoeucgpravskntxhdyqfb"   db "iytpkwnxlsvxrmofzhgaebudjq"   db "nwimzoexrphysfqtvdcgljukda"  time db 'you have take time:$'letter_counter db 0  life_flag db 78 dup(0) position_flag db 78 dup(0)  present_position db 1 start_hour db 0start_min db 0start_second db 0 end_hour db 0end_min db 0end_second db 0data ends stack segment para stack 'stack'  db 64 dup(0) stack ends code segment  main proc far  assume cs:code,ds:data,ss:stack  start: mov ax,data  mov ds,ax  mov letter_counter,00h   mov present_position,1   lea si,position_flag   mov ah,00h  mov cx,00h init_postion_flag:        ;对position_flag依次赋值为00h mov [si],ah       inc si  inc cx  cmp cx,78d  jne init_postion_flag  lea di,letters           lea si,letters_bak  mov cx,00h init_letters:          ;将letters_bak的值赋给letters mov ah,[si]  mov [di],ah  inc si  inc di  inc cx  cmp cx,78d  jne init_letters  mov ah,00h  lea si,life_flag  mov cx,00h init_life_flag:       ;对life_flag依次赋值为00h mov [si],ah  inc si  inc cx  cmp cx,78d  jne init_life_flag  mov cx,00h   mov ah,01h   or ch,00010000b  int 10h clear_screen 00d,00d,24d,79d             ;清屏 Init_game 00d,00d,0ah,dl,80d,nextsign1          ;循环显示边框        Init_game 24d,00d,0ah,dl,80d,nextsign2           Init_game 00d,00d,0ah,dh,25d,nextsign3  Init_game 00d,79d,0ah,dh,25d,nextsign4  menu 05d,15d,ZK                 ;在第5行15列显示ZK menu 07h,15d,no                 ;在第7行15列显示no menu 09d,15d,meg  menu 11d,15d,meg1  menu 13d,15d,meg2  menu 15d,15d,meg3  menu 17d,15d,meg4  put: mov ah,02h                 ;设置光标位置  mov bh,00h  mov dh,22d                       mov dl,33d  int 10h  mov ah,01h                      ;从键盘输入任意字符  int 21h  cmp al,0dh                                       je speed3                       ;是回车转移到speed3 cmp al,45h                      ;空格转移到exit    je exit  exit: mov ah,4ch  int 21h   speed3: mov ax,speed+12  mov speed,ax  jmp begin  ;开始游戏 begin: clear_screen 01d,01d,23d,78d              ;清屏宏调用   clear_screen 01d,01d,23d,78d   Init_game 23d,01d,01h,dl,78d,nextsign5    ;此时dl是33d  ;call  start_time               ;;;;;;;;;;;;;调用之后就不能正常显示字母 mov ah,02h                                ;设置光标位置 mov bh,00h  mov dh,01h  mov dl,01h  int 10h mov cx,00h   lea si,letters                  nextletter:   mov ah,02h                     ;显示letters mov dl,[si]  int 21h  inc si  inc cx  cmp cx,78d  je nextcycle  jmp nextletter from_front:   sub present_position,78d   jmp gobackto_si find_zero:  cmp letter_counter,78d   je recycle  cmp present_position,78d  je from_one  mov ah,00h  nextsi: add present_position,01h  inc si  cmp [si],ah  je gobackto_di  cmp present_position,78d  je from_one  jmp nextsi from_one:mov present_position,01h   jmp gobackto_si  recycle:mov letter_counter,00h  mov present_position,01d  lea si,position_flag  mov cx,00h  mov ah,00h clearsi: mov [si],ah  inc cx  cmp cx,78d je nextcycle  inc si  jmp clearsi nextcycle:   lea di,letters  lea si,position_flag  add present_position,31d              ;32d.present_position是用来指定当前光标的所在列 cmp present_position,78  ja from_front          ;大于则转移gobackto_si:  add si,word ptr present_position  dec si                  ;指定position_flag第32位置 mov ah,[si]              ;获取position_flag第32位置的值 cmp ah,01h  je find_zero gobackto_di:  mov ah,01h  mov [si],ah  add di,word ptr present_position  dec di  mov dl,present_position          ;设置光标位置在present_position处 mov ah,02h   mov bh,00h   mov dh,01h  int 10h  mov cx,00h nextrow: push cx   mov cx,00h out_cycle:                       ; 延迟  push cx  mov cx,00h in_cycle:                    ;这种延迟有点怪。。。。还是用 add cx,01h  cmp cx,1000  jne in_cycle   push dx                    mov ah,06h                     ;从键盘输入字符。AL=输入字符 mov dl,0ffh  int 21h  pop dx  jz pass                    ;上面哪个运算会改变标志位.pop? cmp al,1bh                     ;如果键入ESC,则返回主菜单  je to_start1  cmp al," "                         ;如果键入SPACE,则游戏暂停  je pause  cmp al,[di]                       ;输入字母正确!则字母消失  je disappear pass: pop cx                 ;显示字母 inc cx  cmp cx,speed  je print  jmp out_cycle pause: push dx                   ;暂停处理  mov ah,06h                ;等待输入一个字符 mov dl,0ffh  int 21h  pop dx  cmp al," "  jne pause  jmp pass  to_start1:                      ;返回主菜单 call end_time clear_screen 00,00,24,79  mov ah,09h lea dx,time int 21h mov ah,02h mov dh,10 mov dl,30 int 10h mov bx,0 mov bl,end_hour sub bl,start_hour call take_time mov ah,02h mov dl,':' int 21h mov bx,0 mov bl,end_min sub bl,start_min call take_time mov ah,02h mov dl,':' int 21h mov bx,0 mov bl,end_second sub bl,start_second call take_time mov ah,02h mov dh,11 mov dl,30 int 10h mov ah,09h lea dx,meg5 int 21hput1:  mov ah,01h int 21h cmp al,0dh jz start jmp put1print:   mov ah,0ah                      ;在当前光标位置写空格   mov al," "  mov bh,00h  mov cx,01h  int 10h  inc dh                            ;列号+1 mov ah,02h                     ;改变光标位置  mov bh,00h  int 10h  mov ah,0ah                     ;在当前光标位置写字母   mov al,[di]  mov bh,00h  mov cx,01h  int 10h  pop cx  inc cx  cmp cx,21d                       ;一个字母下落过程中有21行 je print_next_letter  jmp nextrow                    ;下一行 disappear:                      ;击中字母后输出空格  pop cx  pop cx  mov ah,0ah  mov al," "  mov bh,00h  mov cx,01h  int 10h  jmp hit  print_next_letter:   lea si,life_flag  add si,word ptr present_position  dec si  mov ah,0ah  mov al," "  mov bh,00h  mov cx,01h  int 10h  inc dh    mov ah,02h  mov bh,00h  int 10h  mov ah,0ah  mov al," "  mov bh,00h  mov cx,01h  int 10h  mov ah,1  mov [si],ah              ;没击中,将lift_flag相应列号的值设为1 hit: mov ah,02h  mov bh,00h  mov dh,01h  mov dl,present_position  int 10h  mov al,[di] ; 出现下一个新字母的数法  add al,7  cmp al,7ah  ja convey_letter           ;大于z就转 mov ah,0ah                       ;在下落位置处产生一个新字母 mov bh,00h  mov cx,01h  int 10h  mov [di],al  add letter_counter,01h  jmp nextcycle  convey_letter:   sub al,7ah  add al,61h  mov ah,0ah  mov bh,00h  mov cx,01h  int 10h  mov [di],al  add letter_counter,01h  jmp nextcycle   clear_screen 01,01,23,78  mov ah,02h  mov bh,00h  mov dh,11d  mov dl,20d  int 10h  inc dh  inc dh  mov ah,02h  mov bh,00h  int 10h notkey:   mov ah,07h  int 21h  cmp al,0dh  je to_start  cmp al,1bh  je over  jmp notkey to_start:   clear_screen 00,00,24,79  jmp start over: clear_screen 01,01,23,78   mov ah,02h  mov bh,00h  mov dh,11d  mov dl,15h  int 10h  mov ah,02h  mov bh,00h  mov dh,13d  mov dl,15h  int 10h  mov ah,07h  int 21h  mov ah,07h  int 21h  clear_screen 00,00,24,79   mov ax,4c00h  int 21h main endp start_time proc push ax push bx push cx push dx mov ah,2ch int 21h mov start_hour,ch mov start_min,cl mov start_second,dh pop dx pop cx pop bx pop ax retstart_time endpend_time proc push ax push bx push cx push dx mov ah,2ch int 21h mov end_hour,ch mov end_min,cl mov end_second,dh pop dx pop cx pop bx pop ax retend_time endp take_time proc  mov ax,bx  mov cx,0  mov bx,10  let1:  mov dx,0  inc cx  idiv bx  push dx  cmp ax,0  jnz let1  let2:  pop ax  add ax,0030h  mov dl,al  mov ah,2  int 21h  loop let2  rettake_time endp code ends end start ;每次下落后产生一个新字母,下落顺序是每次列号+32,只有小写.通过present_position来控制光标位置
  相关解决方案