zoukankan      html  css  js  c++  java
  • 用汇编编写一个可以自行启动的计算机(纯DOS环境下)

      开机后,CPU自动进入到FFFF:0单元处执行,此处有一条跳转指令。CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序。 初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口地址登记在中断向量表中。 硬件系统检测和初始化完成后,调用int 19h进行操作系统的引导。 如果设为从软盘启动操作系统,则int 19h将主要完成以下工作。 

      (1)控制0号软驱,读取软盘0道0面1扇区的内容到0:7c00; 

      (2)将CS:IP指向0:7c00。 

      软盘的0道0面1扇区中装有操作系统引导程序。int 19h将其装到0:7c00处后,设置CPU从0:7c00开始执行此处的引导程序,操作系统被激活,控制计算机。 如果在0号软驱中没有软盘,或发生软盘I/O错误,则int 19h将主要完成以下工作。 

      (1)读取硬盘C的0道0面1扇区的内容到0:7c00; 

      (2)将CS:IP指向0:7c00。 

      这次课程设计的任务是编写一个可以自行启动的计算机,不需要在现有操作系统环境中运行的程序。 

    该程序的功能如下: 

      (1)列出功能选项,让用户通过键盘进行选择,界面如下 

         1) reset pc          ;重新启动计算机 

         2) start system      ;引导现有的操作系统 

         3) clock             ;进入时钟程序 

         4) set clock         ;设置时间 

      (2)用户输入"1"后重新启动计算机(提示:考虑ffff:0单元) 

      (3)用户输入"2"后引导现有的操作系统(提示:考虑硬盘C的0道0面1扇区)。 

      (4)用户输入"3"后,执行动态显示当前日期、时间的程序。 

      显示格式如下:年/月/日 时:分:秒 

      进入此项功能后,一直动态显示当前的时间,在屏幕上将出现时间按秒变化的效果(提示: 循环读取CMOS)。 

      当按下F1键后,改变显示颜色;按下Esc键后,返回到主选单(提示:利用键盘中断)。 

      (5)用户输入"4"后可更改当前的日期、时间,更改后返回到主选单(提示:输入字符串)。

    assume cs:code
    
    code segment
    ;将程序写在扇区
    begin:  mov ax,0
            mov es,ax
            mov bx,offset start
    
            mov al,1
            mov ch,0
            mov cl,1
            mov dl,0
            mov dh,0
            mov ah,3
            int  13h
    
            add bx,512
            mov al,1
            mov ch,0
            mov cl,2
            mov dl,0
            mov dh,0
            mov ah,3
            int  13h
    
            mov ax,4c00h
            int 21h
    
    start:  jmp main
    
            ;显示菜单
            menu dw cmd0,cmd1,cmd2,cmd3,cmd4,cmd5
            cmd0 db "Command: ",0
            cmd1 db "1) reset pc",0
            cmd2 db "2) start system",0
            cmd3 db "3) clock",0
            cmd4 db "4) set clock",0
            cmd5 db "Enter command: ",0
    
            ;显示年月日(y/m/d)
            clockstr dw cl1,cl2,cl3
            clockcolor db 02h
            cl1 db '00/00/00 00:00:00',0
            cl2 db 'ESC - return menu!',0
            cl3 db 'F1 - change color!',0
            cltable db 9,8,7,4,2,0
    
            ;更改日期
            points dw pointsInput,pointsEnd
            pointsInput db "Enter new date in format YYMMDDHHMMSS: ",0
            pointsEnd db "You have changed date successfully.",0
    
            ;功能模块
            func dw ResetPC,StartSystem,Clock,SetClock
    
    ;主程序
    main:    ;重启时从磁盘读取程序到0:7c00h
            mov ax,0
            mov es,ax
            mov bx,7c00h
    
            mov al,1
            mov ch,0
            mov cl,1
            mov dl,0
            mov dh,0
            mov ah,3
            int  13h
    
            mov bx,7c00h+512
            mov al,1
            mov ch,0
            mov cl,1
            mov dl,0
            mov dh,0
            mov ah,3
            int  13h
    
            call CleanScreen
            mov bx,0
            mov cx,6
            mov di,0
            mov dl,7
    ;显示菜单
    ShowMenu:   push bx
                mov bx,menu[bx]
                call ShowData
                add di,160
                pop bx
                add bx,2
                loop ShowMenu
    
            call MoveCursor
            call ReadCMD
    
            mov ax,4c00h
            int 21h
    
    ;清除当前屏幕
    CleanScreen:    push ax
                    push cx
                    push es
                    push di
    
                    mov ax,0b800h
                    mov es,ax
                    mov di,0
                    mov cx,2000
    
         CSloop:    mov byte ptr es:[di],0
                    add di,2
                    loop CSloop
    
                    pop di
                    pop es
                    pop cx
                    pop ax
                    ret
    
    ;显示数据
    ;bx为偏移地址,di指向显示位置
    ShowData:   push es
                push di
                push cx
                push ax
                push si
                push dx
    
                mov si,0
                mov ch,0
                mov ax,0b800h
                mov es,ax
    
      SDloop:   mov cl,cs:[bx+si]
                jcxz SDend
                mov es:[di],cl
                inc di
                mov es:[di],dl
                inc si
                inc di
                jmp short SDloop
    
       SDend:   pop dx
                pop si
                pop ax
                pop cx
                pop di
                pop es
                ret
    
    ;移动光标
    MoveCursor: push ax
                push bx
                push dx
    
                mov ah,2
                mov bh,0
                mov dh,5
                mov dl,15
                int 10h
    
                pop dx
                pop bx
                pop ax
                ret
    
    ;读取命令
    ReadCMD:    push ax
                push bx
    
    CMDLoop:    mov ah,0
                int 16h
                cmp al,'1'
                jb ReadCMD
                cmp al,'4'
                ja ReadCMD
                sub al,'1'
                mov ah,0
                push ax
                pop bx
                add bx,bx
                call word ptr func[bx]
    
                pop bx
                pop ax
                jmp main
    
    ;重启PC
    ResetPC:    mov ax,0ffffh
                push ax
                mov ax,0
                push ax
                retf
    
    ;引导操作系统
    StartSystem:    mov al,1
                    mov ch,0
                    mov cl,1
                    mov dl,80h
                    mov dh,0
                    mov ah,2
                    int 13h
    
                    mov ax,0
                    push ax
                    mov ax,7c00h
                    push ax
                    retf
    
    Clock:  push ax
            push bx
            push cx
            push dx
            push si
            push di
            push dx
    
            call CleanScreen
    ClockB: mov dl,1
            mov dh,8
    ClockS: mov si,0
            mov di,0
            mov cx,6
    
    Cloop:  push cx
            mov al,cltable[di]
    
            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 cl1[si],ah  
            mov byte ptr cl1[si+1],al
    
            add si,3
            inc di
            pop cx
            loop Cloop
    
    ShowBeg:    mov bx,0
                mov di,0
                mov cx,3
    
    ShowClock:  push bx
                mov bx,clockstr[bx]
                call ShowData
                add di,160
                pop bx
                add bx,2
                loop ShowClock
    
                ;改变颜色或返回
                in al,60h
                cmp al,01h      ;ESC
                je ClockRet
                cmp al,3bh      ;F1
                je ChangeColour
                jmp short ClockS
    
    ChangeColour:   shl dl,1
                    cmp dl,dh
                    je ClockB
                    jmp short ClockS
    
    ClockRet:   pop dx
                pop di
                pop si
                pop dx
                pop cx
                pop bx
                pop ax
                ret
    
    ;设置时钟
    SetClock:   push ax
                push bx
                push cx
                push dx
                push es
                push di
    
                call CleanScreen
                mov bx,0
                mov bx,points[bx]
                mov di,0
                call ShowData
    
                mov cx,6
                mov bx,0
                mov ax,0b800h
                mov es,ax
                mov di,39*2
    
    Input:      push cx
    Input1:     mov ah,0
                int 16h
                cmp al,'0'
                jb Input1
                cmp al,'9'
                ja Input1
                mov es:[di],al
                add di,2
                
                sub al,'0'
                mov cl,4
                shl al,cl
                mov ch,al
    
    Input2:     mov ah,0
                int 16h
                cmp al,'0'
                jb Input2
                cmp al,'9'
                ja Input2
                mov es:[di],al
                add di,2
    
                sub al,'0'
                and al,00001111b
                add al,ch
    
                push ax
                mov al,cltable[bx]
                inc bx
    
                out 70h,al
                pop ax
                out 71h,al
                pop cx
                loop Input
    
                mov bx,2
                mov bx,points[bx]
                mov di,160
                call ShowData
                call Delay
    
                pop di
                pop es
                pop dx
                pop cx
                pop bx
                pop ax
                ret
    
    Delay:      push ax
                push dx
                mov dx,0ch
                mov ax,0
    s1:         sub ax,1
                sbb dx,1
                cmp ax,0
                jne s1
                cmp dx,0
                jne s1
                pop dx
                pop ax
                ret
    code ends
    end begin
  • 相关阅读:
    Android模拟器快捷键
    深度理解依赖注入
    HTTP协议中PUT和POST使用上的区别
    HashMap与HashCode
    HashCode和hashMap hashTable
    apt-get指令的autoclean,clean,autoremove的区别
    Switching JRE Version
    Install Official Eclipse on Ubuntu
    Set Matrix Zeroes
    Unique Paths
  • 原文地址:https://www.cnblogs.com/csuchenzc/p/13409808.html
Copyright © 2011-2022 走看看