荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29 |
今天终于找到了,这个曾经设计程序。
=============================================================================
;课程设计二,首先安装程序计算需要写入到软盘的代码大小,根据代码大小,来决定
;写入扇区的大小。将个这大小存储到Fshanqu标号处,由于这个标号放到了开始位置
;所以安装程序会将这个大小写入到软盘中,这样从软盘启动时,通过读取它,就可以
;得到读取多少个扇区到内存中。
;另外由于bios只负责读取软盘第一扇区,所以需要将软盘读写子程序Floopy写入到软
;盘的的第一扇区中。
;软盘中第一扇区中的程序,负责把软盘的程序全部读取到内存中后,接着跳转到disp
;加载启动菜单。
;--------------------------------------------------------------------------
assume cs:code
code segment
Fstart: jmp short Fok
Fshanqu: dw 0 ;被写入到软盘中的代码占用扇区数,这个值在被写入软盘
Fok: mov ax,cs ;之前,会通过安装代码计算得到。
mov es,ax
mov bx,offset Fshanqu+7c00h ;由于默认是装载到0:7c00h
mov cx,cs:[bx]
mov bx,8e00h ;将软盘中程序加载到0:8e00h
mov dx,0
mov ah,0
Fshanqus: call Floopy ;调用软盘读写子程序
inc dx
add bx,512
loop Fshanqus
mov ax,offset disp-offset Fstart ;disp是软盘启动菜单的开始地址
add ax,8e00h
jmp ax ;跳到disp部份开始执行。
;-------------------------------------------------------------------------
;Floopy子程序是软盘读写程序。
;ah=0 读取软盘中的程序到es:bx指向的内存中
;ah=1 将es:bx指向的内存数据写入到软盘中
;dx值是软盘的逻辑扇区数,它的取值范围为0 ~ 2879。参考王爽汇编实验17(P310)
;-------------------------------------------------------------------------
Floopy: push ax
push dx
push cx
push ax
mov ax,dx
mov dx,0
mov cx,1440
div cx ;ax=int(luojiquhao/1440)
;dx=rem(luojiquhao/1440)
mov cl,al ;cl=mian hao
mov ax,dx
mov ch,18
div ch ;al=int(rem(luojiquhao/1440)/18)=cidaohao
;ah=rem(rem(luojiquhao/1440)/18)
add ah,1 ;ah=shanquhao
mov dx,cx ;dl=cl=mianhao
mov ch,al
mov cl,ah
pop ax
cmp ah,0
je read
cmp ah,1
je white
read: mov dh,dl
mov dl,0
mov al,1
mov ah,2
jmp fpret
white: mov dh,dl
mov dl,0
mov al,1
mov ah,3
fpret: int 13h
pop cx
pop dx
pop ax
ret
;-------------------------------------------------------------------------
disp: mov ax,offset stack+8e00h
mov ss,ax
mov sp,256
mcls: cli
call fuwei
call setint9
call scrcls
sti
sdisp: call mscreen
mov bx,offset restapc+8e00h ;press key 1 restart pc
cmp word ptr cs:[bx+4],1
je disprepc
mov bx,offset stsyspc+8e00h ;press key 2 start system
cmp word ptr cs:[bx+4],1
je dispsys
mov bx,offset clockadr+8e00h;press key 3 show clock
cmp word ptr cs:[bx+4],1
je dispcloc
mov bx,offset setadr+8e00h ;press key 4 set clock
cmp word ptr cs:[bx+4],1
je disptime
mov bx,offset scoladr+8e00h ;press keyF1
cmp word ptr cs:[bx+4],1
je dispmcol
jmp sdisp
disprepc: mov word ptr cs:[bx+4],0
jmp dword ptr cs:[bx]
dispsys: call reint9 ;fuwei int9
call system ;read hard disk
mov ax,7c00h
jmp ax ;start pc
dispcloc: call clock
call reint9
jmp mcls
dispmcol: call showcol
call reint9
jmp mcls
disptime: ; mov ah,0
; int 16h
; cmp ah,5
; jne dispret
call reint9
call setclock
dispret: jmp mcls
;-------------------------------------------------------------------------
;showstr:show chars
;dh=line No.,dl=Row No.
;ds:si=charstr
;-------------------------------------------------------------------------
showstr: push ax
push ds
push es
push si
push di
push cx
push dx
mov al,160
mul dh ;ax=line address
add dl,dl
mov dh,0
add ax,dx
mov di,ax
mov ax,0b800h
mov es,ax
showstrs: mov ch,ds:[si]
cmp ch,0
je showstrok
mov es:[di],ch
add di,2
inc si
jmp showstrs
showstrok: pop dx
pop cx
pop di
pop si
pop es
pop ds
pop ax
ret
;-------------------------------------------------------------------------
;mscreen: show main screen
;-------------------------------------------------------------------------
mscreen: push ax
push bx
push cx
push dx
push si
push ds
push es
mov bx,offset ss8+8e00h
mov ch,0
mov ax,cs
mov ds,ax
mov dh,8
mscreens: mov si,ds:[bx]
mov dl,25
call showstr
add bx,2
inc dh
inc ch
cmp ch,8
je mscreenok
jmp mscreens
mscreenok: pop es
pop ds
pop si
pop dx
pop cx
pop bx
pop ax
ret
;-------------------------------------------------------------------------
;int9 key int
;key 1 set restapc byte4=1
;-------------------------------------------------------------------------
int9: push ax
push si
push cx
push ds
mov si,offset Yint9adr+8e00h
mov ax,cs
mov ds,ax
in al,60h
pushf
call dword ptr ds:[si]
cmp al,2
je key1
cmp al,3
je key2
cmp al,4
je key3
cmp al,5
je key4
cmp al,1
je keyEsc
cmp al,3bh
je keyF1
jmp int9ret
keyEsc: mov si,offset clockadr+8e00h
mov word ptr cs:[si+6],1
mov si,offset Esckeyst+8e00h
mov byte ptr cs:[si],1
jmp int9ret
key1: mov si,offset restapc+8e00h
mov word ptr cs:[si+4],1
jmp int9ret
key2: mov si,offset stsyspc+8e00h
mov word ptr cs:[si+4],1
jmp int9ret
key3: mov si,offset clockadr+8e00h
mov word ptr cs:[si+4],1
jmp int9ret
key4: mov si,offset setadr+8e00h
mov word ptr cs:[si+4],1
jmp int9ret
keyF1: mov si,offset scoladr+8e00h
mov word ptr cs:[si+4],1
int9ret: pop ds
pop cx
pop si
pop ax
iret
;-------------------------------------------------------------------------
;system: read hard disk 0:7c00h
;-------------------------------------------------------------------------
system: push ax
push bx
push cx
push dx
push es
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
pop es
pop dx
pop cx
pop bx
pop ax
ret
;-------------------------------------------------------------------------
;clock: show clock
;-------------------------------------------------------------------------
clock: push ax
push bx
push cx
push dx
push ds
push si
push di
push es
jmp cls
time1: db 9,8,7,4,2,0
time2: db '20yy/mm/dd tt:ss:jj',0
time3: db 2,5,8,11,14,17
cls: mov ax,0b800h
mov es,ax
mov bx,0
mov cx,2000
clss: mov byte ptr es:[bx],' '
add bx,2
loop clss
sclocks:mov ax,cs
mov ds,ax
mov si,offset time1+8e00h
mov bx,offset time3+8e00h
mov cx,6
clockl: push cx
mov di,offset time2+8e00h
mov al,[si]
out 70h,al
in al,71h
mov ah,al
mov cl,4
shr ah,cl
and al,00001111b
add ah,30h
add al,30h
mov cx,0
mov cl,ds:[bx]
add di,cx
mov ds:[di],ah
mov ds:[di+1],al
inc si
inc bx
pop cx
loop clockl
mov dh,12
mov dl,9
mov ax,cs
mov ds,ax
mov si,offset time2+8e00h
call showstr
mov bx,offset clockadr+8e00h
cmp word ptr cs:[bx+6],1
je scret
mov bx,offset scoladr+8e00h
cmp word ptr cs:[bx+4],0
je ccol
call showcol
mov bx,offset scoladr+8e00h
mov word ptr cs:[bx+4],0
ccol: jmp sclocks
scret: pop es
pop di
pop si
pop ds
pop dx
pop cx
pop bx
pop ax
ret
;-------------------------------------------------------------------------
;fuwei: 恢复数据区的功能装态标记子程序。
;-------------------------------------------------------------------------
fuwei: push bx
push es
mov bx,0
mov es,bx
mov bx,offset restapc+8e00h
mov word ptr es:[bx+4],0
mov bx,offset stsyspc+8e00h
mov word ptr es:[bx+4],0
mov bx,offset clockadr+8e00h
mov word ptr es:[bx+4],0
mov word ptr es:[bx+6],0
mov bx,offset scoladr+8e00h
mov word ptr es:[bx+4],0
mov bx,offset setadr+8e00h
mov word ptr es:[bx+4],0
mov bx,offset Esckeyst+8e00h
mov byte ptr es:[bx],0
mov bx,offset yestime+8e00h
mov byte ptr es:[bx],0
mov bx,offset chartop+8e00h
mov word ptr es:[bx],0
pop es
pop bx
ret
;-------------------------------------------------------------------------
;reint9: 恢复原来的int9地址子程序
;-------------------------------------------------------------------------
reint9: push bx
mov bx,offset Yint9adr+8e00h ;fuwei int9
push cs:[bx]
pop cs:[9*4]
push cs:[bx+2]
pop cs:[9*4+2]
pop bx
ret
;-------------------------------------------------------------------------
;setint9: install new int9
;-------------------------------------------------------------------------
setint9: push ax
push bx
push es
cli
mov ax,0
mov es,ax
mov bx,offset Yint9adr+8e00h
push es:[9*4]
pop es:[bx]
push es:[9*4+2]
pop es:[bx+2]
mov word ptr es:[9*4],offset int9+8e00h
mov word ptr es:[9*4+2],0
sti
pop es
pop bx
pop ax
ret
;-------------------------------------------------------------------------
;showcol:改变屏幕色子程序
;-------------------------------------------------------------------------
showcol: push ax
push bx
push cx
push es
mov ax,0b800h
mov es,ax
mov bx,0
mov cx,2000
showcols: inc byte ptr es:[bx+1]
add bx,2
loop showcols
pop es
pop cx
pop bx
pop ax
ret
;-------------------------------------------------------------------------
;scrcls: clear screen
;-------------------------------------------------------------------------
scrcls: push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,0
mov cx,2000
scrclss: mov byte ptr es:[bx],' '
add bx,2
loop scrclss
pop es
pop cx
pop bx
ret
;-------------------------------------------------------------------------
;charstack: 字符串输入栈子程序
;ah=0 入栈,ah=1 出栈,ah=2 显示子字符串
;ds:si 字符串栈空间
;dh=line No.,dl=row No.
;-------------------------------------------------------------------------
charstack: jmp short charstart
chartable: dw charpush+8e00h,charpop+8e00h,charshow+8e00h
chartop: dw 0
charstart: push bx
push dx
push di
push es
push cx
push ax
cmp ah,2
ja sret1
cmp ah,0
jb sret1
jmp sretsta
sret1: jmp sret
sretsta: mov bl,ah
mov bh,0
add bx,bx
mov cx,bx
mov bx,offset chartable+8e00h
add bx,cx
jmp word ptr cs:[bx]
charpush: mov bx,offset chartop+8e00h
push bx
mov bx,cs:[bx]
mov [si][bx],al
pop bx
inc word ptr cs:[bx]
jmp sret
charpop: mov bx,offset chartop+8e00h
cmp word ptr cs:[bx],0
je sret
dec word ptr cs:[bx]
mov bx,cs:[bx]
mov al,[si][bx]
jmp sret
charshow: 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
push di
mov cx,30
ccs: mov byte ptr es:[di],' '
add di,2
loop ccs
pop di
mov cx,0
charshows: mov bx,offset chartop+8e00h
cmp cx,cs:[bx]
jne noempty
mov byte ptr es:[di],'_'
jmp sret
noempty: push bx
mov bx,cx
mov al,[si][bx]
mov es:[di],al
mov byte ptr es:[di+2],'_'
inc bx
mov cx,bx
pop bx
add di,2
jmp charshows
sret: pop ax
pop cx
pop es
pop di
pop dx
pop bx
ret
;-------------------------------------------------------------------------
;getstr字符串输入控制子程序
;-------------------------------------------------------------------------
getstr: push ax
push bx
getstrs: mov ah,0
int 16h
cmp al,20h
jb nochar
mov ah,0
call charstack
mov ah,2
call charstack
jmp getstrs
nochar: cmp ah,0eh
je backspace
cmp ah,1ch
je senter
cmp ah,1
je keyesc1
jmp getstrs
backspace: mov ah,1
call charstack
mov ah,2
call charstack
jmp getstrs
senter: mov al,0
mov ah,0
call charstack
mov ah,2
call charstack
mov bx,offset yestime+8e00h
mov byte ptr cs:[bx],1
jmp charret
keyesc1: mov al,'$'
mov ah,0
call charstack
mov ah,2
call charstack
mov bx,offset Esckeyst+8e00h
mov byte ptr cs:[bx],1
charret: pop bx
pop ax
ret
;-------------------------------------------------------------------------
;setclock: 显示时间设置窗口,并将输入的时间写入到settime2中
;-------------------------------------------------------------------------
setclock: push ds
push si
push ax
push dx
call scrcls
clocks: mov ax,0
mov ds,ax
mov si,offset settime4+8e00h
mov dh,12
mov dl,3
call showstr
mov si,offset settime5+8e00h
mov dh,14
mov dl,3
call showstr
mov si,offset settime2+8e00h
mov dh,14
mov dl,35
mov ax,cs
mov ds,ax
call getstr
mov bx,offset yestime+8e00h
cmp byte ptr cs:[bx],1
je settime
mov bx,offset Esckeyst+8e00h
cmp byte ptr cs:[bx],1
je timeret
jmp clocks
settime: call setdata
timeret: pop dx
pop ax
pop si
pop ds
ret
;-------------------------------------------------------------------------
;setdate子程序,负责把settime2中时间写入到计算机中。
;-------------------------------------------------------------------------
setdata: push ds
push si
push ax
push bx
push cx
push di
push dx
mov ax,cs
mov ds,ax
mov di,offset settime1+8e00h
mov bx,offset settime3+8e00h
mov cx,6
tims: mov si,offset settime2+8e00h
mov dl,ds:[bx]
mov dh,0
add si,dx
mov ax,[si]
push cx
mov cl,4
shl al,cl
and ah,00001111b
or ah,al
pop cx
mov al,ds:[di]
out 70h,al
mov al,ah
out 71h,al
inc bx
inc di
loop tims
pop dx
pop di
pop cx
pop bx
pop ax
pop si
pop ds
ret
;-------------------------------------------------------------------------
;内存数据区,这里有一部分是存放功能状态标记的。
;-------------------------------------------------------------------------
ss0: db 'Floppy disk boot system:',0
ss1: db ' ',0
ss2: db ' 1. Restart PC',0
ss3: db ' 2. Start System',0
ss4: db ' 3. Clock',0
ss5: db ' 4. Set Clock',0
ss6: db ' ',0
ss7: db 'Please input Number(1,2,3,4):_',0
ss8: dw ss0+8e00h,ss1+8e00h,ss2+8e00h,ss3+8e00h,ss4+8e00h,ss5+8e00h,ss6+8e00h,ss7+8e00h
restapc: dw 0,0ffffh,0 ;Byte4=0 No reset pc,Byte4=1 Reset pc
stsyspc: dw 7c00h,0,0 ;byte4=0 No start system,Byte4=1 start system
clockadr: dw clock+8e00h,0,0,0 ;byte6=0循环显示时间,byte6=1停止显示时间
Yint9adr: dw 0,0 ;保存原来int9的地址
fuweiadr: dw fuwei+8e00h,0,0
scoladr: dw 0,0,0 ;byte4=0 不调用clock子程序
setadr: dw 0,0,0,0 ;byte4=0不调用时间设置,byte4=1调用时间设置
settime1: db 9,8,7,4,2,0 ;时间端口地址号
settime2: db '20yy/mm/dd tt:ss:jj',0 ;存储用户输入的数间
settime3: db 2,5,8,11,14,17 ;对settime2时间数字进行位置地址编号
settime4: db 'Input time to press [Enter] key:20yy/mm/dd tt:ss:jj',0
settime5: db ' Please input new time:_',0
Esckeyst: db 0
yestime: db 0
stack: db 256 dup(0) ;stack
;-------------------------------------------------------------------------
Fend: nop
;=========================================================================
start: mov ax,cs
mov es,ax
mov bx,offset Fstart
mov ax,offset Fend-offset Fstart ;计算要被写到软盘中的代码大小
mov dx,0 ;公式为(offset Fend-offset Fstart)/512+1
mov cx,512
div cx
add ax,1
mov cx,ax
push bx
mov bx,offset Fshanqu
mov es:[bx],cx ;将占用扇区数写入到Fshanqu标号处,以便写入到
pop bx ;软盘中
mov dx,0
mov ah,1
s: call Floopy
inc dx
add bx,512
loop s
mov ax,4c00h
int 21h
code ends
end start | | |