《汇编编写 可以自启动的磁盘》

在网上找到大三写的一篇文章,保存到Blog留做纪念!

《汇编编写 可以自启动的磁盘》

下面贴出了两段代码boot.asm 和shell.asm,实现磁盘启动,并且解析了两个命令 time 和 reboot,有兴趣的朋友可以看看。

由于本人的汇编知识很菜,这篇文章只是让大家看看磁盘启动是如何实现的,如果有错误的地方,大家能够指出那就太谢谢了

步骤:放入一张磁盘,把这两段代码编译成EXE,分别执行一次,重启计算机,如果有虚拟系统环境的软件更好,如virtual PC,直接就可以看到效果。

--------------------------------------------------------------------------------

以下是boot.asm

--------------------------------------------------------------------------------


;启动代码
;-----------------------------------------------------

code_seg segment para 'code'
main proc far
assume cs:code_seg,ds:code_seg
org 00h
start:
push ds
sub ax,ax
push ax
mov ax,code_seg
mov ds,ax
mov es,ax

mov ax,0301h ;写1扇区
mov cx,0001h
mov bx,7c00h ;从代码7c00h开始
mov dx,0
int 13h

mov ax,0301h ;写2扇区,数据
mov cx,0002h
mov bx,7e00h ;从代码7e00h开始
mov dx,0
int 13h

ret
org 7c00h ;MBR开始
mov ax,0
mov es,ax

mov ax,201h
mov bx,7e00h ;把2扇区读入7e00h
mov cx,2 ;第二扇区
mov dx,0
int 13h

mov ah,6h ;清屏
mov al,26
mov bh,07h
mov cx,0
mov dh,26
mov dl,80
int 10h

mov ax,1301h ;显示文字
mov bx,04eh
mov cx,18
mov dx,0
lea bp,hello ;7e00h存放着字符串
int 10h

mov ah,3h ;换行
mov bh,0
int 10h
inc dh
mov dl,0
mov ah,2h
mov bh,0
int 10h

jmp init ;跳转到初始化代码

org 7dfeh
db 55h,0aah

org 7e00h ;数据扇区
hello db 'Loading System....'

org 7f00h ;初始化区

init:
mov ax,0
mov es,ax
mov ds,ax

mov ax,201h ;5扇区读入8000h,把命令解释器载入内存
mov bx,8000h
mov cx,5
mov dx,0
int 13h

mov ax,201h ;7扇区读入8400h,把命令处理程序
mov bx,8400h
mov cx,7
mov dx,0
int 13h

jmp command ;跳到命令解释器
org 7ffeh
db 55h,0aah
command: org 8000h

main endp
code_seg ends
end start

--------------------------------------------------------------------------------


以下是shell.asm

--------------------------------------------------------------------------------


;命令解析器
;-------------------------------------------------------------
code_seg segment para 'code'
main proc far
assume cs:code_seg,ds:code_seg
start:
push ds
sub ax,ax
push ax
mov ax,code_seg
mov ds,ax
mov es,ax

mov ax,0301h ;写5扇区
mov cx,0005h
mov bx,8000h ;从代码8000h开始
mov dx,0
int 13h

mov ax,0301h ;写7扇区数据
mov cx,0007h
mov bx,8400h ;从代码8400h开始
mov dx,0
int 13h
ret


org 8000h

kaishi: call printtsf

lea di,command ;命令输入开始
mov dx,0
push dx

begin: mov ah,0h
int 16h

cmp al,0dh ;等于回车
je finish

cmp al,08
jne sast
call backgb
jmp begin

sast: pop dx
cmp dx,13 ;命令最大14字符
ja tolong
inc dx
push dx

stosb ;存储单个字符

mov ah,9h ;打印单个字符
mov bh,0
mov bl,07h
mov cx,1
int 10h

call tuigb ;光标移动

jump1: jmp begin
tolong: push dx ;发出警告声音
mov dx,100
in al,61h
and al,11111100b
sound: xor al,2
out 61h,al
mov cx,140h
wait1: loop wait1
dec dx
jne sound
jmp begin
finish: pop dx
cmp dx,0
je nos
call scroll
nos: call check_com
jmp kaishi

main endp
;------------------------------------------------------------
command db 14 dup(' ') ;6扇区开始
messrb db 'System will reboot now!'
messnf db 'Input command isnot exit!'
tsf db '$'
comlist db 'reboot ',00h,84h
db 'time ',00h,85h
;------------------------------------------------------------
check_com proc near
lea bx,comlist ;便于定位每个命令的首地址
lea di,comlist ;命令表首地址
mov dx,2 ;指令的个数
cmpcom: lea si,command ;存储输入命令地址
cld
mov cx,14
repz cmpsb
jz match
add bx,16
mov di,bx
dec dx
jnz cmpcom

call getgb
mov ax,1301h ;显示文字mess2 NO
mov bx,07h
mov cx,25
lea bp,messnf ;no found地址
int 10h
call scroll

lea di,command ;清空command
mov cx,0014
cld
mov ax,20h
rep stosb
ret
match: add bx,14
call [bx] ;定位命令处理地址

lea di,command ;清空command
mov cx,0014
cld
mov ax,20h
rep stosb
ret
check_com endp
;-------------------------------------------------------------
scroll proc near
call getgb
cmp dh,23 ;是否到达23行
jbe scrend ;判断是否到达屏底
mov dl,0 ;到达屏底,到第1列
call setgb

mov ah,6 ;滚1行
mov al,1
mov bh,07
mov cx,0
mov dh,26
mov dl,80
int 10h
ret
scrend: call getgb
inc dh
mov dl,0
call setgb
ret
scroll endp
tuigb proc near
call getgb
inc dl
call setgb
ret
tuigb endp
;--------------------------------------------------------------
printtsf proc near
mov ah,9h ;打印单个字符$
mov al,tsf
mov bh,0
mov bl,07h
mov cx,1
int 10h
call tuigb
ret
printtsf endp
backgb proc near
call getgb
dec dl
call setgb
ret
backgb endp
getgb proc near
mov ah,3h
mov bh,0
int 10h
ret
getgb endp
setgb proc near
mov ah,2h
mov bh,0
int 10h
ret
setgb endp
org 83feh
db 55h,0aah

org 8400h
reboot proc near
call getgb
mov ax,1301h ;显示文字重启信息
mov bx,07h
mov cx,23
lea bp,messrb ;reboot字符地址
int 10h
call scroll

mov bl,0Feh ;重启命令,利用键盘控制器
xor cx,cx
cmd_wait:
in al,64h
test al,2
jz cmd_send
loop cmd_wait
jmp cmd_error
cmd_send:
mov al,bl
out 64h,al
xor cx,cx
cmd_accept:
in al,64h
test al,2
jz cmd_ok
loop cmd_accept
cmd_error:
mov ah,1
jmp cmd_exit
cmd_ok:
xor ah,ah
cmd_exit:
ret
reboot endp

org 8500h
time proc near
mov ah,4h
int 1ah

push cx

lea di,nowtime
mov al,ch
call bcd2asc
pop cx
mov al,cl
call bcd2asc
inc di
mov al,dh
call bcd2asc
inc di
mov al,dl
call bcd2asc

mov ah,2h
int 1ah

push cx

inc di
mov al,ch
call bcd2asc
inc di
pop cx
mov al,cl
call bcd2asc
inc di
mov al,dh
call bcd2asc

call getgb
mov ax,1301h
mov bx,07h
mov cx,19
lea bp,nowtime ;时间地址
int 10h
call scroll

ret
nowtime db 4 dup(?)
db '\'
db 2 dup(?)
db '\'
db 2 dup(?)
db ' '
db ' ',':',' ',':',' '
time endp

bcd2asc proc near
mov bl,al
mov cl,4
shr al,cl
or al,30h
mov [di],al
inc di
mov al,bl
and al,0fh
or al,30h
mov [di],al
inc di
ret
bcd2asc endp
org 85feh
db 55h,0aah
code_seg ends
;-------------------------------------------------------
end start

--------------------------------------------------------------------------------


完,Thx

 

posted on 2005-12-14 22:29  C# hack  阅读(1405)  评论(0编辑  收藏  举报