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

类别:编程语言 点击:0 评论:0 推荐:

下面贴出了两段代码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

本文地址:http://com.8s8s.com/it/it29500.htm