簡單菜單:在屏幕上顯示一個(gè)簡單的菜單,用戶可以選擇加載哪個(gè)程序或進(jìn)行何種操作。
加載程序 A:顯示作者姓名。
加載程序 B:顯示當(dāng)前日期和時(shí)間。
退出選項(xiàng):通過 cli 和 hlt 實(shí)現(xiàn)關(guān)機(jī)操作。
[BITS 16] ; 16位實(shí)模式
[ORG 0x7C00] ; BIOS加載引導(dǎo)所在的內(nèi)存地址是0x7C00
start:
mov si, welcome_msg ; 加載歡迎信息
call print_string ; 打印字符串
call display_menu ; 顯示菜單
wait_input:
call get_input ; 獲取用戶輸入
call handle_command ; 處理命令
jmp wait_input ; 等待下一次輸入
hang:
hlt ; 停機(jī),等待中斷
jmp hang ; 死循環(huán),保持程序運(yùn)行狀態(tài)
; 打印字符串的子程序
; SI: 指向要打印的字符串
print_string:
mov ah, 0x0E ; BIOS 功能號(hào):在屏幕上顯示字符
.next_char:
lodsb ; 從內(nèi)存中取出當(dāng)前字符(由 SI 指向)并加載到 AL 寄存器
cmp al, 0 ; 判斷當(dāng)前字符是否為字符串結(jié)束符
je .done ; 如果 AL=0(字符串結(jié)束符),跳轉(zhuǎn)到完成
int 0x10 ; 調(diào)用 BIOS 中斷打印字符
jmp .next_char ; 打印下一個(gè)字符
.done:
ret ; 返回主程序
; 顯示菜單
; 在屏幕上顯示可用選項(xiàng)
display_menu:
mov si, menu_msg ; 顯示選項(xiàng)提示信息
call print_string
mov si, option1_msg ; 顯示選項(xiàng)1
call print_string
mov si, option2_msg ; 顯示選項(xiàng)2
call print_string
mov si, option3_msg ; 顯示選項(xiàng)3
call print_string
ret
; 獲取用戶輸入字符
get_input:
mov ah, 0x00 ; BIOS 功能:獲取按鍵
int 0x16 ; 調(diào)用 BIOS 按鍵輸入
mov ah, 0x0E ; 打印用戶輸入的字符
int 0x10
ret
; 處理命令
handle_command:
cmp al, '1' ; 檢查是否選擇1
je load_program_a
cmp al, '2' ; 檢查是否選擇2
je load_program_b
cmp al, '3' ; 檢查是否選擇3
je exit_program
ret ; 如果是其他值,返回菜單
; 加載程序 A
load_program_a:
mov si, program_a_msg ; 顯示作者信息
call print_string
ret
; 加載程序 B
load_program_b:
mov si, program_b_msg ; 顯示時(shí)間信息
call print_string
call display_time ; 顯示當(dāng)前時(shí)間
ret
; 顯示時(shí)間子程序
display_time:
; 獲取 RTC 時(shí)間
mov ah, 0x02 ; BIOS INT 0x1A 功能號(hào):讀 RTC 當(dāng)前時(shí)間
int 0x1A ; 調(diào)用 BIOS RTC 功能
; 顯示時(shí)間:將 CH (時(shí)),CL (分),DH (秒) 轉(zhuǎn)換為 ASCII 并打印
mov si, time_msg
call print_string
mov al, ch ; 獲取當(dāng)前時(shí)
call print_number ; 打印小時(shí)
mov si, colon_msg
call print_string ; 打印冒號(hào)
mov al, cl ; 獲取當(dāng)前分
call print_number ; 打印分鐘
mov si, colon_msg
call print_string ; 打印冒號(hào)
mov al, dh ; 獲取當(dāng)前秒
call print_number ; 打印秒
ret
; 打印數(shù)值的子程序
print_number:
; 將數(shù)值轉(zhuǎn)換為 ASCII
aam ; 分解數(shù)值,AH = 十位,AL = 個(gè)位
add ah, '0' ; 轉(zhuǎn)換十位為 ASCII
int 0x10 ; 打印十位
add al, '0' ; 轉(zhuǎn)換個(gè)位為 ASCII
int 0x10 ; 打印個(gè)位
ret
; Exit program
exit_program:
mov si, exit_msg ; Display exit message
call print_string
jmp hang ; Jump to hang (halt the system)
menu_msg db "Select an option:\n", 0
option1_msg db "1. Load Program A\n", 0
option2_msg db "2. Load Program B\n", 0
option3_msg db "3. Exit\n", 0
welcome_msg db "Welcome to the bootloader!\n", 0
program_a_msg db "Author: John Doe\n", 0
program_b_msg db "Current Date and Time:\n", 0
time_msg db "Time: ", 0
colon_msg db ":", 0
exit_msg db "Exiting program...\n", 0
times 510 - ($ - $$) db 0 ; 填充至510字節(jié)
dw 0xAA55 ; 引導(dǎo)扇區(qū)標(biāo)志