王爽汇编语言课程设计2

来源:互联网 发布:processon类似软件 编辑:程序博客网 时间:2024/05/07 12:42

王爽汇编语言 第二版 课程设计2

编写一个可以自行启动的计算机,不需要在现有操作系统环境中运行的程序

一、相关资料

系统启动初始化完成后最终调用19h,该中断读取软盘的第一扇区或硬盘的第一扇区到0:7c00开始的512个字节的内存空间中,并将cs:ip指向0:7c00执行。

更详细参考王爽汇编语言第二版,课程设计2,p.312

二、设计思路

将安装程序分为三个段,

1、第一个段为安装程序,负责将第二个段写入第一扇区,第三个段写入2-17扇区;

2、第二个段是主引导程序,存在于软盘第一扇区,由BIOS的19h中断读取到0:7c00开始的内存单元中,并执行0:7c00的第一行代码。这一段的任务是将软盘2-17扇区的数据读入内存,并执行。(这里读入到了2000:0开始的内存中)

3、第三个段是系统程序,存放所有引导所需的程序和子程序

三、详细设计

assume cs:setupsg;安装程序;将引导所需的程序写入到软盘setupsg segmentassume cs:setupsgsetup: ;主引导程序安装到第一扇区 mov ax,initsg mov es,ax mov bx,0 mov al,1 mov ch,0 mov cl,1 mov dl,0 mov dh,0 mov ah,3 int 13h ;子程序安装到从第2扇区开始的扇区 mov ax,syssg mov es,ax mov al,15 mov cl,2 mov ah,3 int 13h ;安装结束,返回 mov ax,4c00h int 21hsetupsg ends;主引导程序;包含所有子程序的直接定址表,扇区加载程序,菜单initsg segmentassume cs:initsginit: call loadsys mov ax,2000h push ax mov ax,0 push ax retfloadsys: mov ax,2000h  ;软盘数据读取到2000:0 mov es,ax mov bx,0 mov al,15  ;读取的扇区数 mov ch,0  ;0磁道 mov cl,2  ;2扇区 mov dl,0  ;0号驱动器 mov dh,0  ;0面 mov ah,2 int 13h retinitsg ends;子程序;包含所有菜单需要调用的子过程syssg segmentassume cs:syssg;菜单显示功能menu: jmp near ptr menushow menudata dw offset md0,offset md1,offset md2,offset md3,offset md4,offset md5 md0 db "------ welcome ------",0 md1 db "1) reset pc",0 md2 db "2) start system",0 md3 db "3) clock",0 md4 db "4) set clock",0 md5 db "copyright @ 2010 Shiying,Inc.All rights reserved.",0 systable dw sys_restart,sys_disksys,sys_showclock,sys_setclockmenushow: mov dh,5 mov dl,30 mov bp,0 mov ax,cs mov ds,ax mov cx,5menushow_s: push cx mov si,menudata[bp] mov cl,02h call sys_showstr add bp,2 add dh,2 pop cx loop menushow_s mov si,offset md5 mov dh,23 mov dl,28 mov cl,02h call sys_showstr;处理用户输入sys_input: mov ah,0 int 16h mov bx,0 mov bl,al mov al,30h sub bl,al ;ascii转换为序列号 sub bl,1 ;1-4转换为0-3 cmp bx,0 jb cycle cmp bx,3 ja cycle add bx,bx call word ptr systable[bx]  ;调用菜单功能cycle: jmp short sys_input;重启计算机sys_restart: mov ax,0ffffh push ax mov ax,0h push ax retf;从硬盘引导sys_disksys: call cls mov ax,0h  ;硬盘数据读取到0:7c00 mov es,ax mov bx,7c00h mov al,1  ;读取的扇区数 mov ch,0  ;0磁道 mov cl,1  ;1扇区 mov dl,80h  ;c盘 mov dh,0  ;0面 mov ah,2 int 13h mov ax,0h push ax mov ax,7c00h push ax retf;显示时钟sys_showclock: call cls jmp short clockreadclockdata: clockstr dw offset cl1,offset cl2,offset cl3 clockcolor db 02h cl1 db '00/00/00 00:00:00',0 cl2 db 'press ESC return menu!',0 cl3 db 'press F1 change color!',0 cltable db 9,8,7,4,2,0clockread: mov si,0        ;si指向'yy/mm/dd hh:mm:ss'的首地址 mov di,0        ;di指向9,8,7,4,2,0的首地址 mov cx,6        ;循环次数clockread_s: push cx mov al,cltable[di]    ;从CMOS中读出年份的BCD码 out 70h,al         in al,71h mov ah,al        ;al中位读出的数据 mov cl,4         shr ah,cl        ;ah中为年份的十位数 and al,00001111b    ;al中为年份的个位数 add ah,30h        ;把数值转换为对应的ASCII码 add al,30h        ;同上 mov byte ptr cl1[si],ah    ;把读出的时间写入 mov byte ptr cl1[si+1],al add si,3 inc di pop cx loop clockread_sclockprint: mov dh,6 mov dl,30 mov bp,0 mov ax,cs mov ds,ax mov cx,3clockprint_s: push cx mov si,clockstr[bp] mov cl,clockcolor[0]  ;将颜色值赋值给cl call sys_showstr add bp,2 add dh,2 pop cx loop clockprint_s mov ah,1 ;调用16h中断的1号功能(非阻塞) int 16h cmp al,1bh ;判断是否为ESC je clockreturn ;若是ESC,回到菜单 cmp ah,3bh ;判断是否为F1 je changecolor jmp short clockreadclockreturn: call cls mov ah,0    ;16h中断的1号功能不会清除键盘缓冲区,下次读取还会读出 int 16h     ;调用0号功能清除一次 jmp near ptr menuchangecolor: inc clockcolor mov ah,0    ;16h中断的1号功能不会清除键盘缓冲区,下次读取还会读出 int 16h     ;调用0号功能清除一次 jmp near ptr clockread;设置时钟sys_setclock: jmp short setclock setclockdata db 'Please input time like "yy/mm/dd hh:mm:ss"',0 setsuccess   db  'Set clock successful! Press any key return...',0setclock: call cls mov dh,6 mov dl,20 mov cl,02h mov ax,cs mov ds,ax mov si,offset setclockdata call sys_showstr call getstr  call settime mov dh,10 mov dl,20 mov cl,02h mov ax,cs mov ds,ax mov si,offset setsuccess call sys_showstr mov ah,0 int 16h call cls jmp near ptr menu;ds:si指向时间字符串settime: jmp short seting settable db 9,8,7,4,2,0seting: mov bx,0 mov cx,6settime_s: mov dh,ds:[si] inc si mov dl,ds:[si] add si,2 mov al,30h sub dl,al sub dh,al shl dh,1 shl dh,1 shl dh,1 shl dh,1 or dl,dh mov al,settable[bx] out 70h,al mov al,dl out 71h,al inc bx loop settime_s ret;子程序:接收字符串getstr: push axgetstrs: mov ah,0 int 16h cmp al,20h jb nochar mov ah,0 call charstack mov ah,2 mov dh,8 mov dl,25 call charstack jmp getstrsnochar: cmp ah,0eh je backspace cmp ah,1ch je enter jmp getstrsbackspace: mov ah,1 call charstack mov ah,2 call charstack jmp getstrsenter: mov al,0 mov ah,0 call charstack mov ah,2 call charstack pop ax ret;子程序:字符串入栈,出栈和显示;参数:(ah)=功能号,0入栈,1出栈,2显示;  ds:si指向字符栈空间,对于0号功能,(al)表示入栈字符;  1号功能,(al)返回的字符,对于2号功能,(dh)(dl)字符串在屏幕显示的行列位置charstack: jmp short charstart table dw charpush,charpop,charshow top  dw 0charstart: push bx push dx push di push es cmp ah,2 ja sret mov bl,ah mov bh,0 add bx,bx jmp word ptr table[bx]charpush: mov bx,top mov [si][bx],al inc top jmp sretcharpop: cmp top,0 je sret dec top mov bx,top mov al,[si][bx] jmp sretcharshow: mov bx,0b800h mov es,bx mov al,160 mov ah,0 mul dh mov di,ax add dl,dl mov dh,0 add di,dx mov bx,0charshows: cmp bx,top jne noempty mov byte ptr es:[di],' ' mov byte ptr es:[di+1],02h jmp sretnoempty: mov al,[si][bx] mov es:[di],al mov byte ptr es:[di+2],' ' mov byte ptr es:[di+1],02h inc bx add di,2 jmp charshowssret: pop es pop di pop dx pop bx ret;显示0结尾的字符串;参数:dh=行号,dl=列号,cl=颜色,ds:si指向字符串首地址sys_showstr: push ax push cx push dx push si push bp push es mov ax,0b800h mov es,ax mov al,80*2 ;80*2*行号 mul dh mov dh,0 add dx,dx ;列号*2 add ax,dx mov bp,axshowstr_s: mov ch,ds:[si] cmp ch,0 je showstr_return mov es:[bp],ch inc bp mov es:[bp],cl inc bp inc si jmp short showstr_sshowstr_return: pop es pop bp pop si pop dx pop cx pop ax ret;清屏cls: mov ax,0b800h mov ds,ax mov bx,0 mov cx,24*80*2cls_s: mov byte ptr ds:[bx],0 add bx,2 loop cls_s mov bx,1resetcol: mov byte ptr ds:[bx],07h add bx,2 loop resetcol retsyssg ends;安装过程的第一行指令end setup

四、测试过程

1、测试工具

测试使用Sun VirtualBox虚拟机和仿真虚拟软驱(http://download.csdn.net/source/2209509)

a)安装仿真虚拟软驱以后,我的电脑中会模拟出一个本地磁盘A,可以像真的软盘一样对其进行读写等
b)在windows命令行下对程序进行编译连接,执行后引导代码写入到软盘中

c)新建一个虚拟机,使用软盘A引导,启动虚拟机

0 0
原创粉丝点击