汇编语言课程设计2

本次课程设计任务要求编写一个可以自行启动计算机,不需要在现有操作系统环境中运行的程序
相信书上312页的内容大家已经看过了,但是可能对于它要求实现的4个功能,摸不着头脑,我们来慢慢分析

一.设计思路:
将安装程序分为三个段,
1、第一个段为安装程序,负责将第二个段写入第一扇区,第三个段写入2-17扇区;
2、第二个段是主引导程序,存在于软盘第一扇区,由BIOS的19h中断读取到0:7c00开始的内存单元中,并执行0:7c00的第一行代码。这一段的任务是将软盘2-17扇区的数据读入内存,并执行。(这里读入到了2000:0开始的内存中)
3、第三个段是系统程序,存放所有引导所需的程序和子程序
二.程序:

assume cs:setupsg
;安装程序
;将引导所需的程序写入到软盘
setupsg segment
assume cs:setupsg
setup:
     ;主引导程序安装到第一扇区
      mov ax,initsg
      mov es,ax
      mov bx,0

      mov al,1
      mov ch,0
      mov cl,1
      mov dl,0
      mov dh,0
      mov ah,3
      int 13h

     ;主引导程序安装到第一扇区
      mov ax,syssg
      mov es,ax
      mov al,15
      mov cl,2
      mov ah,3
      int 13h

      mov ax,4c00h
      int 21h
setupsg ends

;主引导程序
;包含所有子程序的直接定址表,扇区加载程序,菜单
initsg segment
assume cs:initsg
init:
     call loadsys
     mov ax,2000h      ;软盘数据读取到2000:0
     push ax
     mov ax,0
     push ax
     retf
loadsys:
     mov ax,2000h
     mov es,ax
     mov bx,0

     mov al,15  ;读取的扇区数
     mov ch,0  ;0磁道
     mov cl,2  ;2扇区
     mov dl,0  ;0号驱动器
     mov dh,0  ;0面
     mov ah,2
     int 13h
     ret
initsg ends

;子程序
;包含所有菜单需要调用的子过程
syssg segment
assume cs:syssg
;菜单显示功能
menu:
     jmp near ptr menushow
     menudata dw offset md0,offset md1,offset md2,offset md3,offset md4
     md0 db "-------welcome-------",0
     md1 db "1)rset pc",0
     md2 db "2)start system",0
     md3 db "3)clock",0
     md4 db "4)set clock",0
     systable dw sys_restart,sys_disksys,sys_showclock,sys_setclock
menushow:
     mov dh,5
     mov dl,30
     mov bp,0
     mov ax,cs
     mov ds,ax
     mov cx,5
menushow_s:
           push cx

           mov si,menudata[bp]
           mov cl,02h
           call sys_showstr
           add bp,2
           add dh,2

           pop cx
           loop menushow_s
;处理用户输入
sys_input:
     mov ah,0
     int 16h
     mov bx,0
     mov bl,al
     mov al,30h
     sub bl,al  ;ascii转换为序列号
     sub bl,1

     cmp bx,0
     jb cycle
     cmp bx,3
     ja cycle
     add bx,bx
     call word ptr systable[bx]   ;调用菜单功能

cycle:jmp short sys_input

;重启计算机
sys_restart:
     mov ax,0ffffh
     push ax
     mov ax,0h
     push ax
     retf

;从硬盘引导
sys_disksys:
     call cls

     mov ax,0h   ;硬盘数据读取到0:7c00
     mov es,ax
     mov bx,7c00h


     mov al,1   ;读取的扇区数
     mov ch,0   ;0磁道
     mov cl,1   ;1扇区
     mov dl,80h   ;c盘
     mov dh,0   ;0面
     mov ah,2
     int 13h

     mov ax,0h
     push ax
     mov ax,7c00h
     push ax
     retf

;显示时钟
sys_showclock:
     call cls
     jmp short clockread
clockdata:
     clockstr dw offset cl1,offset cl2,offset cl3
     clockcolor db 02h
     cl1 db '00/00/00 00:00:00',0
     cl2 db 'press ESC return menu!',0
     cl3 db 'press F1 change color!',0
     cltable db 9,8,7,4,2,0
clockread:
    mov si,0        ;si指向'yy/mm/dd hh:mm:ss'的首地址
    mov di,0        ;di指向9,8,7,4,2,0的首地址
    mov cx,6        ;循环次数
     clockread_s:
                 push cx

                 mov al,cltable[di]   ;从CMOS中读出年份的BCD码
                 out 70h,al
                 in al,71h
                 mov ah,al    ;al中位读出的数据
                 mov cl,4
                 shr ah,cl
                 and al,00001111b
                 add ah,30h
                 add al,30h
                 mov byte ptr cl1[si],ah     ;把读出的时间写入
                 mov byte ptr cl1[si+1],al
                 add si,3
                 inc di

                 pop cx
                 loop clockread_s
clockprint:
     mov dh,6
     mov dl,30
     mov bp,0
     mov ax,cs
     mov ds,ax
     mov cx,3
     clockprint_s:
                  push cx

                  mov si,clockstr[bp]
                  mov cl,clockcolor[0]    ;将颜色值赋值给cl
                  call sys_showstr
                  add bp,2
                  add dh,2

                  pop cx
                  loop clockprint_s
     mov ah,1   ;调用16h中断的1号功能(非阻塞)
     int 16h
     cmp al,1bh   ;判断是否为ESC
     je clockreturn
     cmp ah,3bh
     je changecolor
     jmp short clockread
clockreturn:
     mov clockcolor,02h
     call cls
     mov ah,0
     int 16h
     jmp near ptr menu
changecolor:
     inc clockcolor
     mov ah,0
     int 16h
     jmp near ptr clockread

;设置时钟
sys_setclock:
     jmp short setclock
     setclockdata db 'Please input time like "yy/mm/dd hh:mm:ss"',0
     setsuccess db 'Set clock successful!Press any key return!',0
     seterror db 'input error!please set again!',0
setclock:
     call cls
     mov dh,6
     mov dl,20
     mov cl,02h
     mov ax,cs
     mov ds,ax
     mov si,offset setclockdata
     call sys_showstr
     call getstr
     call settime

     mov ah,0
     int 16h
     call cls
     jmp near ptr menu

;ds:si指向时间字符串
settime:
     jmp short seting
     settable db 9,8,7,4,2,0
seting:
     mov bx,0
     mov cx,6
     settime_s:
               mov dh,ds:[si]
               inc si
               mov dl,ds:[si]
               add si,2
               mov al,30h

               sub dl,al
               sub dh,al
               call junge    ;判断并处理非法输入

               shl dh,1
               shl dh,1
               shl dh,1
               shl dh,1
               or dl,dh
               call check

      loop settime_s
               mov dh,10
               mov dl,20
               mov cl,02h
               mov ax,cs
               mov ds,ax
               mov si,offset setsuccess
               call sys_showstr


    setret:ret

junge:cmp dh,0   ;输入必须是正确范围之内的数字
      jb error
      cmp dh,9
      ja error
      cmp dl,0
      jb error
      cmp dl,9
      ja error
      jmp jungeret

  error:
     mov dh,12
     mov dl,20
     mov cl,02h
     mov ax,cs
     mov ds,ax
     mov si,offset seterror
     call sys_showstr
     call delay
     mov ah,0
     int 16h
     call cls
     jmp near ptr menu

     
jungeret:ret

check:cmp bx,0
      je year
      cmp bx,1
      je month
      cmp bx,2
      je day
      cmp bx,3
      je hour
      cmp bx,4
      je minute
      cmp bx,5
      je minute

    year:
    mov al,settable[bx]
    out 70h,al
    mov al,dl
    out 71h,al
    inc bx
    jmp checkret

    month:
    cmp dl,1h
    jb error1
    cmp dl,12h
    ja error1
    mov al,settable[bx]
    out 70h,al
    mov al,dl
    out 71h,al
    inc bx
    jmp checkret

    day:
    cmp dl,1h
    jb error1
    cmp dl,30h
    ja error1
    mov al,settable[bx]
    out 70h,al
    mov al,dl
    out 71h,al
    inc bx
    jmp checkret

    hour:
    cmp dl,1h
    jb error1
    cmp dl,24h
    ja error1
    mov al,settable[bx]
    out 70h,al
    mov al,dl
    out 71h,al
    inc bx
    jmp checkret

    minute:
    cmp dl,1h
    jb error1
    cmp dl,60h
    ja error1
    mov al,settable[bx]
    out 70h,al
    mov al,dl
    out 71h,al
    inc bx
    jmp checkret

    error1:
     mov dh,12
     mov dl,20
     mov cl,02h
     mov ax,cs
     mov ds,ax
     mov si,offset seterror
     call sys_showstr
     call delay
     mov ah,0
     int 16h
     call cls
     jmp near ptr menu

     
checkret:ret

;子程序:接收字符串
getstr:
       push ax
getstrs:
        mov ah,0
        int 16h
        cmp al,20h
        jb nochar
        mov ah,0
        call charstack
        mov ah,2
        mov dh,8
        mov dl,25
        call charstack
        jmp getstrs
nochar:
        cmp ah,0eh
        je backspace
        cmp ah,1ch
        je enter
        jmp getstrs
backspace:
        mov ah,1
        call charstack
        mov ah,2
        call charstack
        jmp getstrs
enter:  
        mov al,0
        mov ah,0
        call charstack
        mov ah,2
        call charstack

        pop ax
        ret

;子程序:字符串入栈,出栈和显示
;参数:(ah)=功能号,0入栈,1出栈,2显示
; ds:si指向字符栈空间,对于0号功能,(al)表示入栈字符
; 1号功能,(al)返回的字符,对于2号功能,(dh)(dl)字符串在屏幕显示的行列位置
charstack:jmp short charstart
         table dw charpush,charpop,charshow
         top dw 0
charstart:
          push bx
          push dx
          push di
          push es

          cmp ah,2
          ja sret
          mov bl,ah
          mov bh,0
          add bx,bx
          jmp word ptr table[bx]
charpush:
          mov bx,top
          mov [si][bx],al
          inc top
          jmp sret
charpop:
          cmp top,0
          je sret
          dec top
          mov bx,top
          mov al,[si][bx]
          jmp sret
charshow:
          mov bx,0b800h
          mov es,bx
          mov al,160
          mov ah,0
          mul dh
          mov di,ax
          add dl,dl
          mov dh,0
          add di,dx
          mov bx,0
charshows:
          cmp bx,top
          jne noempty
          mov byte ptr es:[di],' '
          mov byte ptr es:[di+1],02h
          jmp sret
noempty:    
          mov al,[si][bx]
          mov es:[di],al
          mov byte ptr es:[di+2],' '
          mov byte ptr es:[di+1],02h
          inc bx
          add di,2
          jmp charshows
sret:
          pop es
          pop di
          pop dx
          pop bx
          ret
;显示0结尾的字符串
;参数:dh=行号,dl=列号,cl=颜色,ds:si指向字符串首地址
sys_showstr:
          push ax
          push cx
          push dx
          push si
          push bp
          push es
          mov ax,0b800h
          mov es,ax
          mov al,80*2
          mul dh
          mov dh,0
          add dx,dx
          add ax,dx
          mov bp,ax
          showstr_s:
                    mov ch,ds:[si]
                    cmp ch,0
                    je showstr_return
                    mov es:[bp],ch
                    inc bp
                    mov es:[bp],cl
                    inc bp
                    inc si
                    jmp short showstr_s
          showstr_return:
                    pop es
                    pop bp
                    pop si
                    pop dx
                    pop cx
                    pop ax
                    ret

cls:
    mov ax,0b800h
    mov ds,ax
    mov bx,0
    mov cx,24*80*2
    cls_s:
          mov byte ptr ds:[bx],0
          add bx,2
          loop cls_s
          mov bx,1
    resetcol:
          mov byte ptr ds:[bx],07h
          add bx,2
          loop resetcol
    ret

;延时程序
delay:
   push ax
   push dx
   mov dx,1000h
   mov ax,0
s1:sub ax,1
   sbb dx,0
   cmp ax,0
   jne s1
   cmp dx,0
   jne s1
   pop dx
   pop ax
   ret

syssg ends
end setup


getstr、charstack、sys_showstr、cls这四个子程序大家应该都不陌生,之前的学习过程中都见到过

这就是本次课设2的代码,可能我的程序依然存在问题,欢迎指正!

注意:
1.在设置时间模块,不但要能设置,还要保证设置的内容是正确的,这是书上没有提及的,但是我们要达到的效果
2.程序调试正确之后,运行时,需要先手动重启虚拟机

三.运行结果

汇编语言课程设计2_第1张图片

课程设计2所需要的Windows xp镜像我已经上传网盘,免费分享给大家,关注我的公众号,菜单栏–>技术相关–>免费资源即可领取,还有网课查答案,包括学习通、智慧树、mooc,内容涵盖计算机、政治等等,还有其他免费资源(简历模板、电子版书籍和考试资料等等),说不准大家会有用(分享干货)!
扫码加关注吧!
汇编语言课程设计2_第2张图片

你可能感兴趣的:(汇编语言)