汇编网首页登录博客注册
youthangel的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态
文章收藏

[2012-11-14 17:51] 课程设计二

comment            ;
1、编写本地程序
                ①把引导程序写入软盘0面0道1扇区
                ②把子程序写到软盘0面0道2—5扇区
        2、编写软盘程序
                ①引导程序,从软盘中读出子程序写到0:200内存中
                ②子程序,菜单,重启、引导现有程序、显示时间、设置时间、清屏
        其中,显示时间中按键改变颜色,设置时间中接受字符串  
;
;#mode=dos
              
        code  segment
                assume    cs:code
      start:
;写软盘的程序
              mov       ax,seg begin
              mov       es,ax
              mov       bx,offset begin

              mov       al,1
              mov       ch,0
              mov       cl,1
              mov       dh,0
              mov       dl,0
              mov       ah,3        ;1扇区的程序
              int       13h         ;将读软盘写内存的程序写入0道0面1扇区
                                    ;怎么确定数据的结尾 

              mov       ax, next
              mov       es,ax
              mov       bx,0
                                    ;2-4扇区的程序 
              mov       al,3        ;几个扇区
              mov       ch,0        ;磁道号
              mov       cl,2        ;开始扇区号
              mov       dh,0        ;磁头号(面)
              mov       dl,0        ;驱动器号
              mov       ah,3        ;功能号
              int       13h
;退出         
              mov       ax,4c00h
              int       21h
              
                        
;------------------------第一步结束----------------------------              
      begin:                     
              mov       ax,2000h;?????????????错误一0:200处不能写入,不知道为什么
              mov       es,ax
              mov       bx,0
                             
              mov       al,3;共3三个扇区
              mov       ch,0
              mov       cl,2;开始扇区
              mov       dl,0
              mov       dh,0
              mov       ah,2
              int       13h         ;将2-4扇区的子程序写入0:204
              
              mov                ax,2000h
              push        ax
              mov                ax,0
              push        ax
              retf
;--------------------------第二步完成--------------------------                    
        code  ends
        next        segment
;用直接定址表
              jmp       main;错误二,如果使用直接定址表的话需要用段去封装以保证其偏移能对应上。并且必须把子程序放到段开始的位置
       table  dw        rest,sys,clock,stck                ;table的偏移为2
       main:
              
              call      menu
              mov       ah,00h
              int       16h 
              mov       cx,1
              mov       ah,9
              int       10h 
              
              sub       al,31h;把ASCII转换成对应数字
              cmp       al,3
              ja        return
              mov       bx,0
              mov       bl,al
              add       bx,bx
              call      word ptr table[bx]
     return:
              jmp       short main
;---------------------主菜单--------------------------------  
        
      datam   db        "1)    reset pc#"
              db        "2)    start system#"
              db        "3)    clock#"
              db        "4)    set clock#"
              db        "Please enter your choose$"
       menu:
                               mov                bh,2;清屏后为绿色
                         call                clear
              mov       ax,cs
              mov       ds,ax
              mov       si,offset datam        ;设置显示数据的指向
;设置光标
              mov       bh,0        ;0页
              mov       dh,5        ;行
              mov       dl,15       ;列
;显示属性
              mov       bl,2        ;字符属性
              mov       bh,0        ;第0页
          s:
              mov       ah,2
              int       10h         ;置光标
              mov       al,[si]
              inc       si
              cmp       al,'$'
              je        ret1
              cmp       al,'#'
              je        special
              mov       cx,1
              mov       ah,9
              int       10h         ;显示字符
              inc       dl
              jmp       short s
    special:
              mov       dl,15
              add       dh,3
              jmp       short s
       ret1:
              mov       dh,19       ;行
              mov       dl,15       ;列
              mov       ah,2
              int       10h
              ret
;四个子程序
 ;---------------------重启子程序----------------------- 
       rest:
              mov                ax,0ffffh
              push        ax
              mov                ax,0
              push        ax              
              retf
;------------------引导原有操作系统------------- 
     sys:                             
              mov       ax,0
              mov       es,ax
              mov       bx,7c00h
              mov       al,1
              mov       ch,0
              mov       cl,1
              mov       dh,0
              mov       dl,80h      ;硬盘
              mov       ah,2
              int       13h
              
              mov                        ax,0
              push                ax
              mov                        ax,7c00h
              push                ax
              retf                  
;----------------------显示时钟子程序---------------------------- 
      clock:
                              push                ax
                              push                bx
                              push                cx
                              push                ds
                              push                es
                              push                si
                              push                di;保护现场
               push     bp;保护现场 
                              
                              mov                bh,1;清屏后为蓝色
                              call                clear                                                                          
              mov                        bl,1;文字颜色
         get_key:                                               
                         call                ok   ;调用显示时间程序                     
                         mov                ah,01h;检测键盘输入
                         int                16h
                         cmp                al,0
                         je                get_key;如果没有输入,继续检测。做成中断就比较好了
                                        mov                ah,0
                                        int                16h;有输入的话,就分析安键
                                        cmp                ah,3bh;F1
                                        je                        chgcolor
                                        cmp                ah,01h;ESC
                                        je                        back
                                        jmp                get_key;其他按键忽略        
;返回                                
                        back:
                                        pop           bp
                                        pop                di
                                        pop                si
                                        pop                es
                                        pop                ds
                                        pop                cx
                                        pop                bx
                                        pop                ax                                        
              ret  
         chgcolor:          
                          mov                ax,0b800h
                          mov                ds,ax
                          mov                si,1
                          mov                cx,2000
                          inc                bl
          change:
                          mov                [si],bl
                          add                si,2
                          loop                change
                          jmp                get_key                                     
         ok:
                   push      ax
              push      bx
              push      cx
              push      ds
              push      si
              push      es
              push      di
              push      bp          ;保护现场 
              jmp                        begins
          addre: db        9,8,7,4,2,0 ;单元地址;年月日时分秒
                       temp:  dw        8 dup(0)
               begins:        
              mov       ax,cs
              mov       ds,ax
              lea       si,addre
              lea       bx,temp
              mov       bp,0
              mov       cx,6
;从端口里取数据,转换后放入temp里              
         s1:
              mov       al,[si]
              out       70h,al
              in        al,71h
              mov       ah,al
              
              and       ah,00001111b
              push      cx
              mov       cl,4
              shr       al,cl
              pop       cx
              
              mov       [bx],ax
              cmp       bp,2
              jb        g           ;/
              ja        d           ;:
              mov       al,-10h
              jmp       cz
          g:  mov       al,'/'-30h
              jmp       cz
          d:  mov       al,':'-30h
              jmp       cz
          cz:
              mov       [bx+2],al
              inc       si
              inc       bp
              add       bx,3
              loop      s1
              mov       ax,'$'      ;结束标志
              mov       [bx],ax
              
;从temp里取出数据显示,遇到$结束             
              lea       bx,temp
              mov       ax,0b800h
              mov       es,ax
              mov       di,160*7+30*2
         s0:
              mov       al,[bx]
              cmp       al,'$'
              je        ret0
              add       al,30h
              mov       es:[di],al             
              inc       bx
              add       di,2
              loop      s0
       ret0:
              mov       al,20h
              mov       es:[di-2],al
              
              pop       bp
              pop       di          ;恢复现场
              pop       es
              pop       si
              pop       ds
              pop       cx
              pop       bx
              pop       ax
              ret                                       
                          
  ;设置时钟
                stck:                                 
                                jmp                setk
                addre2: db        9,8,7,4,2,0 ;单元地址;年月日时分秒
                time          db                        16 dup(0)
                mseg:         db                        "Please enter time like:yy/mm/dd hh:mm:ss",'$'
                setk:
                                mov        bh,2
                                call        clear
                                
                                mov        ax,cs
                                mov        ds,ax
                                lea        si,mseg;不同地方,lea还是比较好使的
                                
                                mov        ax,0b800h
                                mov        es,ax
                                mov        di,6*160+50
                                
                print:
                                mov        al,[si]
                                cmp        al,'$'
                                je                retp
                                mov        es:[di],al
                                add        di,2
                                inc        si
                                jmp        print
                retp:
                                add        di,480-80
                                mov        bx,0                                
                intime:
                                mov        ah,0
                                int        16h
                                cmp        ah,0eh;退格键
                                je                backsp
                                cmp        ah,1ch
                                je                set
                                cmp        bx,12;只允许输入12个字符
                                je                set
                                mov        es:[di],al;显示
                                cmp        al,'/';过滤字符
                                je                guo
                                cmp        al,' ';过滤字符
                                je                guo
                                cmp        al,':';过滤字符
                                je                guo
                                mov        time[bx],al;保存用户的输入time的段前缀使CS
                                inc        bx
                guo:                                
                                add        di,2
                                jmp        intime
                backsp:
                                cmp        bx,0
                                je                intime;输入为空不能在减了                                
                                sub        di,2;显示减2
                                mov        al,es:[di]
                                cmp        al,' '
                                je                ca
                                cmp        al,'/'
                                je                ca
                                cmp        al,':'
                                je                ca
                                dec        bx;存储减一                                
                ca:        
                                mov        al,' '
                                mov        es:[di],al
                                jmp        intime
                                ;设置栈,实现backspace,和字符的输入显示
;根据输入设置时钟                                
                set:        mov        time[bx],'$';结束标志符,防止用户输入错误
                                lea        si,time
                                lea        bx,addre2
                complex:                                
                                mov        ax,[si];取出字符        
                                cmp        al,'$';检查边界
                                je                retset
                                sub        ax,3030h;ah存BCD码的个位,al存BCD码的十位
                                mov        cl,4
                                shl        al,cl;al左移四位
                                add        ah,al;合成8位
                                mov        al,[bx];取出地址
                                out        70h,al
                                mov        al,ah
                                out        71h,al;写入内容
                                inc        bx;指向下一个地址
                                add        si,2;si指向下一个
                                jmp        complex
                retset:                                
                                ret
                
;读取键盘,返回主菜单

;----------------------清屏程序-----------------------------
      clear:
              mov       al,0        ;滚动的行数,0为清屏
              ;mov       bh,2        ;清屏后默认的属性
              mov       ch,0        ;左上角Y
              mov       cl,0        ;左上角X
              mov       dh,24       ;右下角y
              mov       dl,79       ;右下角X
              mov       ah,06h      ;功能号06向上滚动,07向下滚动
              int       10h
              ret
              
                delay:
                
              push      ax
              push      bx
              push      cx
              mov       bx,1
                ;执行完33144次是0.5s
      again:  mov       cx,33144
      waitf:
              in        al,61h      ;跟61h端口的pb4有关
              and       al,10h
              cmp       al,ah
              je        waitf
              mov       ah,al
              loop      waitf
              dec       bx
              jnz       again
              pop       cx
              pop       bx
              pop       ax
              ret              
      next ends
              end       start
评论次数(0)  |  浏览次数(356)  |  类型(汇编作业) |  收藏此文  | 
 
 请输入验证码  (提示:点击验证码输入框,以获取验证码