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