郑小夕 发表于 2011-12-11 21:38:26

谁知道 王爽的课程设计2 怎么解决

本帖最后由 郑小夕 于 2012-7-16 18:55 编辑

怎么解决

郑小夕 发表于 2011-12-11 21:38:58

对于 实模式 不是很了解。

zzmatrix 发表于 2011-12-12 09:50:08

assume cs:code

code segment

;===============================================================

;功能:将代码写入0面0道1扇区

;入口参数:

;    (ah)=int 13h的功能号(2表示读扇区,3表示写扇区)

;    (al)=写入的扇区数

;    (ch)=磁道号

;    (cl)=扇区号

;    (dh)=磁头号(面号)

;    (dl)=驱动器号    软区从0开始,0:软驱A,1:软驱B

;                        硬盘从80h开始,80h:硬盘C,81h:硬盘D

;    es:bx指向将写入磁盘的数据或指向接收从扇区读入数据的内存区

;返回参数:

;    操作成功:(ah)=0,(al)=写入的扇区数

;    操作失败:(ah)=出错代码

;===============================================================

start:

   mov ax,floppyend-floppy

   mov dx,0

   mov bx,512

   div bx      ;商ax为所需的扇区数

   inc al      ;写入的扇区数(为余数加扇区)



   push cs

   pop es

   mov bx,offset floppy   ;es:bx指向要被写入的内存单元



   mov ch,0 ;磁道号

   mov cl,1 ;扇区号

   mov dl,0 ;驱动器号,软盘A

   mov dh,0 ;磁头号(面号)

   mov ah,3 ;int 13h的功能号(3表示写扇区)

   int 13h       ;将代码写入0面0道1扇区



   mov ax,4c00h

   int 21h



floppy:

   jmp read

;===============================================================

;直接定址表

;===============================================================

table    dw function1-floppy,function2-floppy

   dw function3-floppy,function4-floppy



menu db '***main Menu***',0

   db '1) reset pc    ',0

   db '2) start system',0

   db '3) clock       ',0

   db '4) set clock   ',0

   db 'Please Choose: ',0



time db 'YY/MM/DD hh:mm:ss',0

cmos db 9,8,7,4,2,0

hint db 'press F1 to change the color, press Esc to return',0



hint1    db 'Please input: YY/MM/DD hh:mm:ss',0

char db '//   ::',0



;===============================================================

;功能:将0面0道2扇区的内容写入0:7e00h

;入口参数:

;    (ah)=int 13h的功能号(2表示读扇区)

;    (al)=写入的扇区数

;    (ch)=磁道号

;    (cl)=扇区号

;    (dh)=磁头号(面号)

;    (dl)=驱动器号    软区从0开始,0:软驱A,1:软区B

;                        硬盘从80h开始,80h:硬盘C,81h:硬盘D

;    es:bx指向将写入磁盘的数据

;返回参数:

;    操作成功:(ah)=0,(al)=写入的扇区数

;    操作失败:(ah)=出错代码

;===============================================================

read:

   mov ax,floppyend-floppy

   mov dx,0

   mov bx,512

   div bx      ;商ax为所需的扇区数

   inc al



   mov bx,0

   mov es,bx

   mov bx,7e00h;es:bx指向要读入的内存单元



   mov ch,0 ;磁道号

   mov cl,2 ;扇区号

   mov dl,0 ;驱动器号

   mov dh,0 ;磁头号(面号)

   mov ah,2 ;int 13h的功能号(2表示读扇区)

   int 13h       ;读取0面0道2扇区的内容到0:7e00h处

            ;(第二扇区从512/200h开始)



   mov ax,7c0h

   push ax       ;push cs

   mov ax,showmenu-floppy

   push ax       ;push ip

   retf   ;jmp showmenu



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

;显示主菜单,调用show_str、clean子程序

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

showmenu:

   call clean    ;清屏

   push cs

   pop ds

   mov si,menu-floppy

   mov dh,8

   mov dl,30

   mov cx,6

showmenu0:

   push cx

   mov cl,2

   call show_str

   add si,16

   inc dh

   pop cx

   loop showmenu0



;===============================================================

;接收键盘输入,跳转相应功能程序段

;调用BIOS用来提供读取键盘缓冲区功能的中断例程int 16h,

;将读取的扫描码送入ah,ASCII码送入al

;===============================================================

go:mov ax,0

   int 16h

   cmp al,'1'

   jb showmenu

   cmp al,'4'

   ja showmenu



   sub al,31h

   mov bl,al

   mov bh,0

   add bx,bx

   add bx,3 ;计算相应子程序在table中的位移

   call word ptr cs:



   jmp showmenu



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

;功能1:重新启动计算机

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

function1:

   mov ax,0ffffh

   push ax

   mov ax,0

   push ax

   retf   ;jmp ffff:0



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

;功能3:进入时钟程序

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

function3:

   push ax

   push bx

   push cx

   push dx

   push si

   push ds

   push es

   call clean    ;清屏

   mov dh,0 ;行号

   mov dl,0 ;列号

   mov cl,2

   mov si,offset hint-floppy

   call show_str ;显示提示信息

;===============================================================

;名称:clock

;功能:动态显示当前日期、时间

;===============================================================

   mov cx,2 ;显示颜色

clock:   mov bx,offset cmos-floppy

   mov si,offset time-floppy

   push cx

   mov cx,6

clock0:push cx

   mov al,

   out 70h,al    ;将al送入地址端口70h

   in al,71h ;从数据端口71h处读出单元内容

   mov ah,al

   mov cl,4

   shr al,cl ;右移4位

   and ah,0fh    ;al分成两个表示BCD码值的数据

   add ax,3030h;BCD码+30h=10进制数对应的ASCII码

   mov ,ax   ;ASCII码写入time段

   inc bx

   add si,3

   pop cx

   loop clock0

;---------------------------------------------------------------

;按下F1键后,改变显示颜色

;按下Esc键后,返回主菜单,其他键照常处理

;---------------------------------------------------------------

   mov al,0

   in al,60h

   pop cx      ;显示颜色

   cmp al,3bh    ;和F1的扫描码3bh比较

   je colour

   cmp al,1 ;和esc的扫描码01h比较

   je clockend

   jmp show_clock

col_1:   mov cx,1 ;cl∈,0为黑色

   jmp show_clock

colour:cmp cx,7

   je col_1

   inc cx

show_clock:

   mov dh,12 ;行号

   mov dl,30 ;列号

   mov si,offset time-floppy

   call show_str

   jmp clock ;循环显示CMOS

clockend:

   pop es

   pop ds

   pop si

   pop dx

   pop cx

   pop bx

   pop ax

   ret



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

;功能4:设置时间

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

function4:

   push ax

   push bx

   push cx

   push dx

   push si

   call clean



   mov dh,8 ;行号

   mov dl,30 ;列号

   mov cl,2

   mov si,offset hint1-floppy

   call show_str ;显示提示信息



   add dh,1 ;行号

   add dl,14 ;列号

   mov si,offset char-floppy   ;ds:si指向字符栈空间

   call show_str ;显示输入格式

   mov di,0

   call getstrs

   call witein

   call cleanchar

   pop si

   pop dx

   pop cx

   pop bx

   pop ax

   ret



;===============================================================

;清除char内输入数据,还原环境

;===============================================================

cleanchar:

   push cx

cleanchar1:

   mov cx,di

   jcxz cleanchar2

   call charpop

   jmp cleanchar1

cleanchar2:

   pop cx

   ret



;===============================================================

;ASCII=>BCD,写入CMOS

;===============================================================

witein:

   push si

   mov cx,6

   mov bx,offset cmos-floppy

wite:    push cx

   mov al,

   out 70h,al    ;将al送入地址端口70h

   mov ax,

   sub ah,30h    ;10进制数对应的ASCII码-30h=BCD码

   sub al,30h

   mov cl,4

   shl al,cl ;左移4位

   add al,ah ;al为8位BCD码

   out 71h,al    ;从数据端口71h处写入单元内容

   add si,3

   inc bx

   pop cx

   loop wite

   pop si

   ret

;===============================================================

;子程序:接收数字输入

;参数说明:di=char栈顶(字符地址、个数记录器)

;===============================================================

getstrs:

   push ax

   push bx

getstr:mov ax,0

   int 16h

   cmp ah,0eh         ;退格键的扫描码

   je backspace

   cmp ah,1ch         ;Enter键的扫描码

   je enter1

   cmp al,'0'

   jb getstr

   cmp al,'9'

   ja getstr

   cmp di,16   ;限制输入个数

   ja enter1

   call charpush      ;字符入栈

   call show_str      ;显示栈中字符

   jmp getstr

backspace:

   call charpop       ;字符出栈

   call show_str      ;显示栈中字符

   jmp getstr

enter1:call show_str      ;显示栈中字符

   pop bx

   pop ax

   ret

   

;===============================================================

;子程序:数字的入栈。

;参数说明:ds:si指向char栈空间;(al)=入栈字符;

;===============================================================

charpush:

   mov bx,di

   mov ,al

   inc di

   cmp di,2

   je adds

   cmp di,5

   je adds

   cmp di,8

   je adds

   cmp di,11

   je adds

   cmp di,14

   je adds

   ret

adds:    inc di

   ret



;===============================================================

;子程序:数字的出栈。

;参数说明:ds:si指向char栈空间;(al)=入栈字符;

;===============================================================

charpop:cmp di,0

   je sret            ;栈顶为0(无字符),结束

   cmp di,3

   je subs

   cmp di,6

   je subs

   cmp di,9

   je subs

   cmp di,12

   je subs

   cmp di,15

   je subs

   dec di

   mov bx,di

   mov al,' '

   mov ,al

   ret

subs:    sub di,2

   mov bx,di

   mov al,' '

   mov ,al

   ret

sret:    ret



;===============================================================

;名称:show_str子程序

;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。

;参数:(dh)=行号(取值范围0~24);

;      (dl)=列号(取值范围0~79);

;      (cl)=颜色;

;      ds:si指向字符串的首地址。

;返回:无。

;===============================================================

show_str:

   push ax

   push bx

   push cx

   push dx

   push si

   push es

   mov ax,0b800h

   mov es,ax

   mov ax,160

   mul dh

   mov bx,ax ;bx=160*dh

   mov ax,2

   mul dl      ;ax=dl*2

   add bx,ax ;mov bx,(160*dh+dl*2)设置es:bx指向显存首地址

   mov al,cl ;把颜色cl赋值al

   mov cl,0

show0:   mov ch,

   jcxz show1    ;(ds:si)=0时,转到show1执行   

   mov es:,ch

   mov es:.1,al

   inc si      ;ds:si指向下一个字符地址

   add bx,2 ;es:bx指向下一个显存地址

   jmp show0

show1:   pop es

   pop si

   pop dx

   pop cx

   pop bx

   pop ax

   ret



;===============================================================

;名称:clean子程序

;功能:清屏

;===============================================================

clean:   push bx

   push cx

   push es

   mov bx,0b800h

   mov es,bx

   mov bx,0

   mov cx,2000

clean0:mov byte ptr es:,' '

   add bx,2

   loop clean0

   pop bx

   pop cx

   pop es

   ret



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

;功能2:引导现有的操作系统

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

;===============================================================

;功能2实现引导现有的操作系统,代码需要将硬盘的0面0道1扇区读入0:7c00,

;会覆盖从软盘读到0:7c00的第一个扇区,所以功能2代码不能写在第一个扇区

;===============================================================

function2:

   call clean

   mov ax,0

   mov es,ax

   mov bx,7c00h



   mov al,1 ;读取的扇区数

   mov ch,0 ;磁道号

   mov cl,1 ;扇区号

   mov dl,80h    ;驱动器号

   mov dh,0 ;磁头号(面号)

   mov ah,2 ;int 13h的功能号(2表示读扇区)

   int 13h       ;读取0面0道1扇区的内容到0:7c00h处



   mov ax,0

   push ax       ;push cs

   mov ax,7c00h

   push ax       ;push ip

   retf   ;jmp 0:7c00h



floppyend:nop



code ends

end start


页: [1]
查看完整版本: 谁知道 王爽的课程设计2 怎么解决