王爽《汇编语言》

来源:互联网 发布:淘宝向顾客要好评话术 编辑:程序博客网 时间:2024/05/22 16:04
王爽《汇编语言》课程设计2

assume cs:code
code segment
        begin:
                mov ax,cs
                mov es,ax
                mov bx,offset start
;---------------------------------------------从BX开始写入磁盘----------------------------------
                mov dl,0
                mov dh,0
                mov ch,0
                mov cl,1
                mov al,19
                mov ah,3
                int 13h
;---------------------------------------------从BX开始写入磁盘结束----------------------------------       

                mov ax,4c00h
                int 21h
               
;----------------------------------------------程序结束----------------------------------------------

;----------------------------------------------启动时从扇区中读取数据到内存--------------------------
        start:
                mov ax,0
                mov es,ax
                mov bx,7c00h
                add bx,512

                mov dl,0
                mov dh,0
                mov ch,0
                mov cl,2                       
                mov al,18                      
                mov ah,2
                int 13h
                jmp start1
                db 500 dup(?)
        start1:
                jmp menu

;menu-------------------------------------
        menu:   ;名称:菜单程序
                ;功能:显示一个菜单
                ;参数:无
                ;返回值:无
                jmp short menustart

        mn:     db "1) reset pc",0      ;重启计算机
                db "2) start system",0  ;引导现有操作系统
                db "3) clock",0         ;进入时钟程序
                db "4) set clock",0     ;设置时间
        mt1:    dw     offset resetpc-offset start,offset startsys-offset start
                dw     offset clock-offset start,offset resetclock-offset start
        menustart:
        menus0:
                mov ax,0b800h         ;指向显示位置
                mov es,ax
                mov di,0


                mov ax,cs               ;指向数据位置
                mov ds,ax
                mov si,offset mn-offset start
                add si,7c00h

                mov cx,0
        menus:                          ;循环显示以‘0’结尾的字符串
                mov al,ds:[si]
                cmp al,0
                jz menuso
                mov es:[di],al
                inc si
                add di,2
                jmp menus
        menuso:
                inc cx
                cmp cx,4
                jz menuin
                inc si
                mov ax,160
                mul cx
                mov di,ax
                jmp menus
               
;---------------------------------------menu显示完毕-----------------------------------------
              
        menuin:                         ;1-9的扫描码为02-0A或者也可以比较ASCII码
                mov ah,0
                int 16h
               
                cmp al,35h
                jae menuin
                cmp al,30h
                jbe menuin
;---------------------------------------检测输入是否符合条件------------------------------

         
                mov ah,al
                sub ah,30h
        menus2: nop

        mjmp:   mov bx,offset mt1-offset start       ;调用相应的子程序
                add bx,7c00h
                dec ah                                ;扫描码比真实的大1
                mov al,ah
                add al,al
                mov ah,0
                add bx,ax
                mov ax,ds:[bx]
                add ax,7c00h                          ;找到真实的程序的地址
                call ax
                call cls
                jmp menus0                             ;返回显示菜单

        menuover:
                nop
               

 
;menu-------------------------------------

;resetpc------------------------------------------
        resetpc:        ;名称:resetpc
                        ;功能:重启计算机
                        ;参数:无
                        ;返回值:无
                push ax
                push ds
                push si

                jmp short rpstart
        rpstack:dw 0,0ffffh
        rpstart:
                mov ax,cs
                mov ds,ax
                mov si,offset rpstack-offset start
                add si,7c00h
                call dword ptr ds:[si]

                pop si
                pop ds
                pop ax
                ret

;resetpcend---------------------------------------
;==================================================================================
;startsys------------------------------------------------------
        startsys:       ;名称:STARTSYS
                        ;功能:引导现有的操作系统
                        ;参数:无
                        ;返回值:无
                call cls
                push ax
                push bx
                push cx
                push dx
                push es
                push si
               
               
                jmp short startsys2
        startsys1:
                dw 7c00h,0
        startsys2:
                mov ax,0
                mov es,ax
                mov bx,7c00h

                mov dl,80h                                         ;现有的操作系统。
                mov dh,0
                mov ch,0
                mov cl,1
                mov al,1
                mov ah,2
                int 13h

                mov si,offset startsys1-offset start
                add si,7c00h
                call dword ptr cs:[si]                           ;代码已经从硬盘上复制到7c00h处,指向该处,该处存放着0:7c00h

                pop si
                pop es
                pop dx
                pop cx
                pop bx
                pop ax
                ret

 data1     db 16 dup(0)
 data2     db 9,8,7,4,2,0,' '
 data3     db '/','/',' ',':',':',' '
 
;startsysend---------------------------------------------------
;=========================================================================================================
;clock-----------------------------------------
    clock:
         push ax
         push di
         push si
         push dx
         push cx
         push es
        
;-----------------------------------------------------
        push cs
        pop ds

        mov ax,0
        mov es,ax
        mov si,offset int9  -offset start + 7c00h
        mov di,207h
        mov cx,offset int9end-offset int9
        cld
        rep movsb
       
        push es:[9*4]
        pop es:[200h]
        push es:[9*4+2]
        pop es:[202h]

        cli                         ;在改变int9中断的代码的地址时发生可屏蔽中断,所以先将F1置0
        mov word ptr es:[9*4],207h
        mov word ptr es:[9*4+2],0
        sti
       

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

       
        mov ax,0b800H
        mov es,ax
       
      
    clockok:

       mov al,cs:[204]
       mov byte ptr cs:[204],0
       cmp al,01h
       je okend

       
        mov si,0
        mov di,160*12+20*2
       
       
     s1:
        mov al,cs:[offset data2 - offset start + 7c00h+si]
        out 70h,al
        in al,71h

        mov ah,al
        mov cl,4
        shr ah,cl             
        and al,00001111b          ;将内存中的数据转换成两位数的字符
 

        add ah,30h
        add al,30h
       
        mov byte ptr es:[10*160+4*2],ah
        mov byte ptr es:[10*160+5*2],al
 
        mov byte ptr es:[di],ah
        mov byte ptr es:[di+2],al
        mov al,cs:[offset data2 -offset start +7c00h +si+7]
        mov byte ptr es:[di+4],al
        mov al,cs:[offset data2 -offset start + 7c00h +si]
        cmp al,0
        je clockok
       
    
       
        inc si
        add di,6

       
        jmp short s1
       


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

 int9:
        push ax
        push bx
        push cx
        push es

        in al,60h
  
  pushf
  call dword ptr cs:[200h]

        mov cs:[204],al
        cmp al,3bh
        jne int9ret
       
        mov ax,0b800h
        mov es,ax
        mov bx,1
        mov cx,80*25
       
        mov al,0                          ;颜色取时钟的秒钟,每发生一次int9,就会改变一次颜色,即每摁下一次F1就会改变一次颜色
        out 70h,al
        in al,71h
      
    s2:
        and byte ptr es:[bx],11111000b           
        and al,00000111b
        or es:[bx],al
        inc bx
        inc bx
        loop s2
int9ret:
        pop es
        pop cx
        pop bx
        pop ax
        iret
       

int9end:nop

okend:  pop es
        pop cx
        pop dx
        pop si
        pop di
        pop ax
        ret
;-----------------------------------------------------
 cls:       push ax
            push di
            push cx
           
            mov cx,80*25
            mov di,0
            mov ax,0b800h
            mov es,ax
        s:  mov es,ax
            mov byte ptr es:[di],' '
            inc di
            inc di
            loop s
           
            pop cx
            pop di
            pop ax
            ret
;=========================================================================================================
;resetclock------------------------------------------------
        resetclock:     ;名称:resetclock
                        ;功能:修改CMOS中的时间
                        ;参数:(输入,两位阿拉伯数字)
                        ;返回值:无
                       
            push ax
            push bx
            push cx
            push si
            push di
            push es

            mov word ptr cs:[205],0
            mov si,0
           
 getstr:    push ax
           
 getstrs:   mov ah,0
            int 16h

            cmp al,20h                      ;读取输入的ASCII码
            jb nochar
            mov ah,0                        ;输入的是字符,则调用,ah传递的是功能号,即一个字符入栈
            call charstack              
            mov ah,2                        ;调用功能打印字符串
            call charstack                
            jmp getstrs                     ;始终循环检测
           
           
  nochar:   cmp ah,0eh
            je backspace
            cmp ah,1ch
            je enter
            jmp getstrs
          
    resetclockok:
   
            pop es
            pop di
            pop si
            pop cx
            pop bx
            pop ax
            ret
           
 backspace: mov ah,1
            call charstack
           
            call cls
           
            mov ah,2
            call charstack
            jmp getstrs
           
 enter:     mov al,0
            mov ah,0
            call charstack
            mov ah,2
            call charstack
    
            call changetime
 
            pop ax
            jmp resetclockok
           

charstack:  jmp short charstart

table   dw offset charpush - offset start +7c00h,offset charpop -offset start + 7c00h ,offset charshow -offset start +7c00h
;top     dw 0


charstart:  push bx
            push dx
            push di
            push es
           
            cmp ah,2                          ;ah为传递过来的功能号参数
            ja sret
            mov bl,ah
            mov bh,0
            add bx,bx
            jmp word ptr cs:[offset table -offset start + 7c00h+bx]
           
 charpush:  mov bx,word ptr cs:[205]
            mov cs:[offset data1 -offset start + 7c00h + si+bx],al
            inc word ptr cs:[205]
 
          
           
            jmp sret
           
  charpop:  cmp word ptr cs:[205],0
            je sret
            dec word ptr cs:[205]
            mov bx,word ptr cs:[205]
            mov al,cs:[offset data1 -offset start + 7c00h +si+bx]
            jmp sret
           
 charshow:  mov bx,0b800h
            mov es,bx
           
            mov dh,12                              ;初始化行列
            mov dl,20
           
           
            mov al,160
            mov ah,0
            mul dh                                 ;dh,dl的输入问题
            mov di,ax
            add dl,dl
            mov dh,0
            add di,dx
           
            mov bx,0
           
 charshows: cmp bx,word ptr cs:[205]
            jne noempty
            mov byte ptr es:[si],' '
            jmp sret
           
 noempty:   mov al,cs:[offset data1 - offset start + 7c00h +si+bx]
            mov es:[di],al
            inc bx
            add di,2
            jmp charshows
           
 sret:      pop es
            pop di
            pop dx
            pop bx
            ret
           

changetime:  
            push bx
            push dx
            push di
            push es
           
           ; cmp bp,18  ;如果长度不等于18就退出,不改CMOS
           ; jne endenter

   changclock:
            mov si,0   ;指向开始的数据
           ; mov bp,0  ;指向开始的端口号
               
       ;     mov bx,16
            mov di,0
            mov cx,6           ;年月日时分秒,共6次
           
 changloop:
            mov dx,70h
            mov al,cs:[offset data2 -offset start +7c00h+di]
            out dx,al          ; 向70h写入了要访问的单元
                          
            mov dx,71h         ;将端口71h预存到dx中,待会将向该端口写数据
            mov ah,byte ptr cs:[offset data1 -offset start + 7c00h +si]  ;得到年在al
            mov al,byte ptr cs:[offset data1 -offset start + 7c00h +si+1]
            sub ah,30h
            sub al,30h
           
            push cx            ;保护cx
            mov cl,4
            shl ah,cl          ;把年的十位移到高4位
            pop cx
           
            and al,00001111b   ;把年的个位高4位清0
            or al,ah           ;把一个完整的年分合并到al一个字节中
            out dx,al          ;把年写入CMOS
           
            inc si
            inc si             ;指向下一个时间单位
           
            inc di             ;指向下一个端口号
                    
            loop changloop         

  endenter: pop es
            pop di
            pop dx
            pop bx
            ret
      ;-----更改时间结束-----------------------------    

 

 
;charstackend-----------------------------------------------

;==========================================================================================================

code ends
end begin

原创粉丝点击