1. 程式人生 > 實用技巧 >用匯編編寫一個可以自行啟動的計算機

用匯編編寫一個可以自行啟動的計算機

  開機後,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