免费下载应用软件、交流使用经验。

软件下载 经验交流 软件开发 专题论述 请君留言 网站介绍 休闲时光 返回主页
 
《ZERO多系统启动选择》软件源程序代码

汇编语言

作者:本人   来源:本站

;**********************************************************

;*                                                        *

;*    多操作系统启动选择程序 ZEROHD.ASM --硬盘启动程序      *

;*                                                        *

;*        编制:胡家峻 1999.8-2000.4 江西.宜春 (C)          *

;*            TEL:0795-3245707 (目前已停用)              *

;*          http://softroom.163.net(已停用)             *

;*          E-mail:softroom@163.net(已停用)              *

;**********************************************************

code segment                     ;汇编程序开始

assume cs:code,es:code

org 100h

begin proc far                   ;程序开始

                                 ;屏幕初始显示

xor ax,ax

push ax                          ;将段指针指向00H

pop ax

push ax

pop ax

mov ax,600h

mov bh,17h                      ;屏幕属性(或bh=01)

xor cx,cx                       ;左上角y,x座标

mov dx,184fh                    ;右下角y,x座标

int 10h                         ;清蓝色屏幕

mov bx,offset zero1             ;取数据串地址

mov ax,1fdbh                    ;背景=1,前景=e,字符=<空格>

mov cx,26h                      ;共38项

call redisp                     ;调用重复显示子程序

mov bx,offset zero2             ;ES:BP=源串的段:位移

call disp2                      ;显示"V 0.12"

mov bx,offset zero3             ;ES:BP=源串的段:位移

call disp2                      ;显示"Copyright by hujiajun"

mov bx,offset zero4             ;ES:BP=源串的段:位移

call disp2                      ;显示"http://softroom.soim.com"

mov bx,offset zero5             ;ES:BP=源串的段:位移

call disp2                      ;显示"E-mail:softroom@163.net"

mov bx,offset zero6             ;ES:BP=源串的段:位移

call disp2                      ;显示"Welcome to ZERO"

mov bx,offset zero7             ;ES:BP=源串的段:位移

call disp2                      ;显示"2000.04"

mov al,1eh

mov es:winc,al

mov ax,3fc4h                    ;重复62次,显示横线

mov dx,908h

call disp3

mov ax,9dbh

mov dx,es:disx

call disp3                      ;显示9个' ?'

mov ax,3fc4h

mov dx,1608h

call disp3                      ;在23行显示单横线

mov al,es:cal0

add al,30h

mov ah,1

mov dx,172dh                    ;显示剩余秒数

call disp3

                                ;屏幕显示完毕,开始读引导扇区及分区ID号

mov bx,7dc2h                    ;设置分区数据指针

xor cl,cl

mov dx,offset sele1             ;ID保存地址

b1: mov al,es:[bx]              ;读出分区ID号

cmp al,0

jz b3                           ;空分区转移

xchg dx,bx

mov es:[bx],al                  ;保存分区ID

inc bx

inc cl

xchg dx,bx

mov al,es:[bx-4]                ;取活动标志

cmp al,80h

jnz b2

mov es:sele0,cl                 ;记录活动分区号

mov es:men1,cl                  ;设置菜单默认项

b2: add bx,10h

cmp cl,4

jnz b1                          ;读下一分区数据

                                ;分区系统ID及活动分区标志读完,计算显示菜单的总项数

b3: mov es:men0,cl              ;保存总菜单项数

                                ;取菜单项总数,准备将系统的ID号转换成菜单显示的代号

mov bx,offset sele1             ;分区菜单号开始地址

mov dx,offset idcode            ;码表开始地址

b4: mov al,es:[bx]              ;读ID号

xchg bx,dx

xlat                            ;换码

xchg bx,dx

mov es:[bx],al                  ;保存菜单显示代号

inc bx

dec cl

jnz b4

                                ; 开始显示菜单

bb0: mov ch,1                   ;设当前菜单显示项

mov cl,es:men0                  ;取总显示项

mov bx,offset sele1             ;取显示代号地址

mov dx,offset menu              ;取菜单字符起始地址

beg5: push bx                   ;ch=当前显示的菜单项序号

push cx                         ;cl=显示的菜单项总数

push dx                         ;bx=菜单显示序号开始地址

xor ah,ah                       ;dx=菜单显示字符开始地址

mov al,es:[bx]                  ;取当前显示的序号

mov cl,4                        ;乘以16(左移4位)

sal ax,cl

add ax,dx                       ;计算出当前菜单显示字符串地址

mov bp,ax

mov al,ch                       ;取当前显示的菜单条号

add al,0ah                      ;加上起始行号

mov dh,al                       ;当前显示的行号

mov dl,20h                      ;当前显示的列号

mov cx,10h                      ;显示的字符串长度(固定为16个字)

mov bx,17h                      ;显示的页号及属性

mov ax,1300h

int 10h                         ;显示当前菜单条

pop dx

pop cx

pop bx

inc bx                          ;下一菜单条显示序号

inc ch                          ;下一菜单项号

dec cl

jnz beg5                        ;继续显示下一菜单条

                                ;菜单条显示完毕, 置定时器中断1Ch,准备计时(待以后修改)

mov ax,[0070h]                  ;取原中断入口数据

mov ds:int1c0,ax                ;保存原中断

mov ax,[0072h]

mov ds:int1c1,ax

mov ax,0e95eh                   ;置中断向量

mov es:[0070h],ax

mov ax,900bh

mov es:[0072h],ax

even

menu0: call disp1                ;显示当前菜单

me1: mov ah,1

int 16h                          ;检测键盘

jnz me2                          ;有键按下,跳转

cmp es:chk,1

jz me1                           ;已经有键按下过, 但本次未按键

                                 ;检查计时, 定时无按键即自动选择原活动分区(前次选择的分区)

cmp es:cal1,12h

jb me1                           ;未满一秒,跳转

mov dx,es:disx                   ;取行列号(dh=行,dl=列)

inc dx

mov es:disx,dx                   ;保存行,列号

mov ax,920h

mov bl,1eh                       ;蓝底黄字

mov es:winc,bl                   ;用空格覆盖进度条

call disp3

mov al,es:cal0

cmp al,0

jz m20

dec al

mov al,es:cal0

add al,30h

mov ah,1

mov dx,172dh              ;显示剩余秒数

call disp3

cmp dl,2dh

jnz me1                   ;继续检测按键

jmp menu6                 ;等待时间已到,跳转启动默认分区

even

                          ;处理按键

me2: cmp es:chk,1

jz me3

mov ax,ds:int1c0

mov ds:[0070h],ax

mov ax,ds:int1c1

mov ds:[0072h],ax

pop es

                          ;有键按下, 停止自动计时, 恢复原中断

m20: mov al,1

mov es:chk,al             ;置已按键标志

me3: xor ah,ah            ;清键盘缓冲区

int 16h

push ax

call disp1                ;当前菜单条反相显示

pop ax                    ;恢复键码

cmp ah,15

jnz menu3                 ;非TAB键转移

                          ;菜单光条下移处理

menu1: mov al,es:men1     ;取当前菜单条号

cmp al,es:men0            ;与总菜单条数比较

jnz menu2                 ;不相等跳转

xor al,al                 ;当前菜单号置0

menu2: inc al             ;菜单号增1

mov es:men1,al            ;保存当前菜单号

jmp menu0

even

menu3: cmp ah,80

jz menu1                  ;下移箭头转跳格键处理

cmp ah,77

jz menu1                  ;右移箭头转跳格键处理

cmp ah,72

jnz menu5                 ;不是上移键, 跳转

                          ;菜单条上移处理

menu31: mov al,es:men1    ;上移键处理,取当前菜单号

dec al                    ;菜单号减1

cmp al,0

jnz menu4

mov al,es:men0            ;若是首行则转末行

menu4: mov es:men1,al     ;保存当前菜单号

jmp menu0

even

menu5: cmp ah,75

jz menu31                 ;左移键转上移处理

menu51: cmp ah,57

jz menu6                  ;空格键确认

cmp ah,28

jz menu6                  ;回车键确认

jmp menu0

even

                          ;确认选中处理

menu6: mov bx,offset sele0 ;取菜单条号起始地址

mov al,es:men1            ;取当前菜单项号

xor ah,ah

add ax,bx                 ;计算当前菜单条号地址

mov bx,ax

mov al,es:[bx]            ;取当前菜单条的代码

cmp al,13h                ;可启动的分区代码从14h开始

menu62: jnb menu9

                          ;选中的菜单条是不能启动的分区(代号小于11H),警告处理

mov bx,offset mess8       ;显示数据地址

mov al,47h                ;显示属性为红底白字

call win                  ;调窗口子程序

jmp menu0                 ;转菜单

                          ;选中了可启动的分区

even

menu9: mov al,es:sele0    ;取当前活动分区号

cmp al,es:men1            ;与当前菜单选项比较

jz menu91                 ;选中的分区本身就是活动分区

mov cl,4                  ;计算原活动分区号的地址

sal al,cl

xor ah,ah

mov bx,7daeh

push bx

add bx,ax

xor al,al

mov es:[bx],al            ;取消原活动分区标志(置0)

mov al,es:men1            ;计算选中的分区号地址

mov cl,4

sal al,cl

xor ah,ah

pop bx

add bx,ax

mov al,80h

mov es:[bx],al            ;置新活动分区标志

mov ax,301h

mov bx,7c00h

mov cx,1

mov dx,80h

int 13h                   ;将引导扇区的内容写回硬盘

menu91: mov al,es:men1    ;准备读选中分区的自举扇区

mov cl,4

sal al,cl                 ;分区号乘以16后加基数

xor ah,ah

mov bx,7daeh

add ax,bx                 ;计算选中分区数据的起始地址

mov bx,ax

mov dx,es:[bx]            ;取磁盘及柱面号

mov cx,es:[bx+2]          ;取磁道及扇区号

mov bx,7c00h

mov ax,201h

int 13h                   ;读分区自举扇区数据

jmp 7c00h                 ;跳转执行分区自举程序

db 0

db 0

db 0

begin endp

even

redisp proc near         ;重复显示子程序

                         ;al=要显示的字符码,ah=显示属性

re0: push cx             ;写入的项数

mov dx,es:[bx]           ;取列号,行号

inc bx

inc bx

push bx                  ;保存数据指针

push ax                  ;保存字符及属性

xor bh,bh

mov ah,2

int 10h                  ;置光标位置

pop ax                   ;恢复字符及属性

pop bx                   ;恢复指针

xor ch,ch

mov cl,es:[bx]           ;取重复值

inc bx

push bx                  ;保存指针

push ax                  ;保存字符及属性

mov bl,ah                ;置写入属性

xor bh,bh

mov ah,0ah

int 10h

pop ax

pop bx

pop cx

loop re0                ;显示下一项

ret

redisp endp

even

disp1 proc near         ;菜单反相显示

mov al,es:men1          ;取当前菜单项

add al,0ah              ;加上起始行

mov dh,al               ;行座标

mov dl,1bh              ;列座标

disp10: push dx         ;保存行列座标

mov ah,2

xor bh,bh

int 10h                 ;置光标位置

mov ah,8

xor bh,bh

int 10h                 ;取光标位置的字符和属性

not ah                  ;属性取反

and ah,7fh              ;屏蔽高位

mov bl,ah

mov cx,1                ;长度1

mov ah,9

xor bh,bh

int 10h                 ;光标位置写入

pop dx

inc dl                  ;列号加1

cmp dl,34h

jnz disp10

mov dx,1900h

xor bh,bh

mov ah,2

int 10h                 ;隐蔽光标

ret

disp1 endp

even

disp2 proc near         ;封面信息显示子程序

mov dx,es:[bx]          ;取行号列号

inc bx

inc bx

mov cl,es:[bx]          ;取信息字符长度

inc bx

mov ch,es:[bx]          ;取显示属性

inc bx

mov bp,bx               ;置字符地址

mov bl,ch               ;置属性

xor ch,ch

xor bh,bh               ;置显示页

mov ax,1300h

int 10h

ret

disp2 endp

                        ;重复显示子程序

even

disp3 proc near         ;定位显示模块

push ax                 ;ah=显示长度,al=显示字符

mov cl,ah               ;dx=显示行列号

xor ch,ch

push cx

mov ah,2

xor bh,bh

int 10h                 ;置光标

pop cx

pop ax

mov ah,9

xor bh,bh               ;显示页面

mov bl,es:winc          ;取显示属性

int 10h

ret

disp3 endp

                        ;保存窗口的内容,显示指定的信息,定时或按键后恢复窗口内容

even

win proc near           ;对话窗口子程序

mov es:winc,al          ;保存显示属性

xor al,al

mov es:wint,al          ;分行显示清零

mov es:winm,al

                        ;计算窗口左右列号(上下行号固定为0bh-10h)

mov al,[bx]             ;取信息长度

inc bx

push bx                 ;保存信息地址

cmp al,49h              ;信息长度大于73则分两行显示

jb win0

sub al,40h              ;减去基本长度

mov es:wint,al          ;保存剩余长度

mov al,40h

win0: add al,5          ;加空白边

mov es:winw,al          ;保存宽度

mov bl,al

sar al,1                ;右移一位(除以2)

mov ah,al

mov al,27h

sub al,ah               ;计算左列号

mov es:winl,al          ;保存左列号

add al,bl

dec al

mov es:winr,al          ;保存右列号

                        ;保存窗口内容

mov dh,0bh              ;对话框从11行开始

mov ch,6                ;固定6行高

mov bx,3000h            ;取缓存地址

win1: mov dl,es:winl    ;取左列号

mov cl,es:winw          ;取宽度

win2: push dx           ;开始保存窗口字符及属性

push cx

push bx

xor bh,bh               ;置页号

mov ah,2

int 10h                 ;置光标位置

mov ah,8

xor bh,bh

int 10h                 ;读光标位置字符及属性

pop bx

mov [bx],ax             ;保存字符及属性

inc bx

inc bx

pop cx

pop dx

inc dl                  ;列号加1

dec cl

jnz win2                ;本行未完,继续

inc dh                  ;行号加1

dec ch

jnz win1                ;未完,继续下一行

                        ;窗口内容保存完毕,清窗口

xor bh,bh               ;页面

mov bh,es:winc          ;取属性

mov cl,es:winl          ;取左列号

mov dl,es:winr          ;取右列号

mov ch,0bh              ;开始行号

mov dh,10h              ;结束行号

mov ax,600h

int 10h                 ;清窗口

                        ;画窗口框线

mov ax,1c9h             ;c9=左上角表格线, 长度1

mov dl,es:winl          ;左上角行列

mov dh,0bh

call disp3              ;调定位显示子程序

mov dl,es:winl

inc dl

mov dh,0bh

mov ah,es:winw

dec ah

dec ah                  ;长度

mov al,0cdh             ;cd=上边表格线

call disp3

mov dh,0bh

mov dl,es:winr

mov ax,1bbh             ;bb=右上角表格线,长度1

call disp3

mov dl,es:winl

mov dh,10h

mov ax,1c8h             ;c8=左下角表格线,长度1

call disp3

mov ah,es:winw

dec ah

dec ah                  ;宽度

mov al,0cdh             ;cd=下边表格线

mov dl,es:winl

inc dl

mov dh,10h

call disp3

mov dl,es:winr

mov dh,10h

mov ax,1bch             ;bc=右下角表格,长度1

call disp3

mov dh,0ch              ;显示两边竖线,从0ch行开始

mov cl,4                ;共4行

win3: push cx

push dx

mov dl,es:winl          ;左边列号

mov ax,1bah             ;ba=表格竖线,长度1

push dx

push ax

call disp3

pop ax

pop dx

mov dl,es:winr          ;右边列号

call disp3

pop dx

inc dh                  ;行号加一

pop cx

dec cl                  ;次数减一

jnz win3                ;未完继续显示

                        ;显示窗口信息

pop bx

push bx

mov bp,bx               ;置显示信息地址

xor bh,bh               ;页面

mov bl,es:winc          ;取显示属性

mov al,es:winw

sub al,6

mov cl,al               ;显示信息长度

xor ch,ch

mov al,es:winl

add al,3

mov dl,al               ;显示信息的列号

mov dh,0dh              ;显示信息的行号

mov ax,1300h

push dx

int 10h                 ;显示第一行信息

pop dx

pop bx

cmp es:wint,0

jz win4

inc dh

mov ax,40h

add ax,bx

mov bp,ax

mov dl,es:wint          ;第二行信息的长度

mov cl,dl

sar dl,1

mov al,27h

sub al,dl

mov dl,al

xor ch,ch

mov bl,es:winc

xor bh,bh

mov ax,1300h

int 10h                 ;显示第二行信息

win4: mov dx,1900h

xor bh,bh

mov ah,2

int 10h                 ;隐蔽光标

                        ;等待按键

xor ah,ah

mov winm,al             ;清标志

int 16h                 ;读键盘

and al,3fh              ;屏蔽高二位(大写转换为小写)

cmp al,39h              ;'Y'确认键

jnz win5

mov al,1

                        ;恢复窗口内容

win5: mov dh,0bh        ;对话框从11行开始

mov ch,6                ;固定6行高

mov bx,3000h            ;取缓存地址

win6: mov dl,es:winl    ;取左列号

mov cl,es:winw          ;取宽度

win7: push dx           ;开始恢复窗口原字符及属性

push cx

push bx

mov ah,2

xor bh,bh               ;置页号

int 10h                 ;置光标位置

pop bx

mov ax,es:[bx]          ;取字符及属性

push bx

mov bl,ah               ;置属性

mov ah,9

xor bh,bh

mov cx,1

int 10h                 ;写光标位置字符及属性

pop bx

inc bx

inc bx

pop cx

pop dx

inc dl                  ;列号加1

dec cl

jnz win7                ;本行未完,继续

inc dh                  ;行号加1

dec ch

jnz win6                ;未完,继续下一行

cmp es:winm,0

jz win8

clc                     ;清c标志

jmp win9

win8: stc

win9: ret

win endp

even

winw db 0               ;对话框宽度

winl db 0               ;对话框左列号

winr db 0               ;对话框右列号

winc db 1eh             ;对话框属性

winm db 0               ;>0,对话框确认标志

wint db 0               ;>0,第二行显示的信息长度

even

int1c proc near         ;定时器中断(计时)模块

inc es:cal1             ;计数

ret

even

int1c0 dw 0             ;保存原时钟中断代码

int1c1 dw 0

int1c endp

even

                        ;操作系统ID转换表

idcode db 0,14h,19h,0,15h,1,16h,0,0,0,0,17h,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,1bh,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

menu db "Can't know Sys "

db "DOS Expand Parti" ;05

db "2 "

db "3 "

db "4 "

db "5 " ;

db "6 "

db "7 " ;

db "8 "

db "9 " ;

db "A "

db "B " ;

db "C " ;

db "D "

db "E " ;

db "F "

db "10 "

db "Setup ZERO 0.12 "         ;固定为11H开始

db "Reple old system"

db "Reple ZERO 0.12 "

db "DOS (12 bit FAT)" ;01

db "DOS (16 bit FAT)" ;04

db "DOS or WIN 9.X " ;06

db "DOS (32 bit FAT)" ;0b

db "Windows NT 4.X "

db "XENIX root " ;02

db "Xteam Linux 1.0 "

db "NOVELL " ;64

even

sele0 db 0                    ;当前的活动分区

sele1 db 0                    ;第一分区ID号

sele2 db 0                    ;第二分区ID号

sele3 db 0                    ;第三分区ID号

sele4 db 0                    ;第四分区ID号

sele5 db 0

sele6 db 0

sele7 db 0

sele8 db 0

sele9 db 0

selea db 0

seleb db 0

selec db 0

chk db 1                      ;键按下标志

cal0 db 9                     ;总*计数

cal1 db 0                     ;秒计数

disx dw 1722h                 ;23行34列开始显示*号

men0 db 0                     ;总菜单条数

men1 db 0                     ;当前菜单条号

                              ;(空格)ZERO显示数据

zero1 db 10,2,5,17,2,5,24,2,4

db 32,2,3,14,3,1,17,3,1

db 24,3,1,28,3,1,31,3,1

db 35,3,1,13,4,1,17,4,1

db 24,4,1,28,4,1,31,4,1

db 35,4,1,12,5,1,17,5,4

db 24,5,4,31,5,1,35,5,1

db 11,6,1,17,6,1,24,6,1

db 26,6,1,31,6,1,35,6,1

db 10,7,1,17,7,1,24,7,1

db 27,7,1,31,7,1,35,7,1

db 10,8,5,17,8,5,24,8,1

db 28,8,1,32,8,3

even

zero2 db 2eh,5,6,1bh,"V 0.12"    ;界面显示

even

zero3 db 2eh,6,15h,1bh,"Copyright by Hujiajun"

even

zero4 db 2eh,7,23,1bh,"http://softroom.163.net"

even

zero5 db 2eh,8,23,1bh,"E-mail:softroom@163.net"

even

zero6 db 20h,15h,10h,1eh,"Welcome to ZERO!"

even

zero7 db 47h,18h,7,17h,"2000.04"

                                  ;对话框、警告框提示信息(因本人的英语太差,下面的错误请协助更正)

even

mess4 db 1dh,'Do you wish to continue?(y/n)'

                                  ;你想继续吗?

even

mess5 db 1ch,'Press any key to continue...'

                                  ;按任意键继续...

even

mess8 db 46h,'The partition of selected is not any system,press any key to continue.'

                                  ;选中的分区没有任何操作系统,按任意键继续。

code ends

end begin


2006.4.18

发表日期: 2005-4-26   修改日期:2006-10-9

备案序号:赣ICP备05002359号

建议使用1024*768分辩率浏览 ☆版权所有 摘抄或转载须得到书面许可☆ Hujiajun ©1999,2016
E-Mail: hu-jj@21cn.com