. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->使用BIOS进行键盘输入和磁盘读写
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  关于课程2,我看到许多人都是使用固定磁盘扇区数,而不是通过由写磁盘程序部份自动计算需要多少磁盘扇区数  [待解决] 回复[ 3次 ]   点击[ 434次 ]  
vs9841
[帖 主]   [ 发表时间:2013-06-25 10:00 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29
关于课程2,我看到许多人都是使用固定磁盘扇区数,而不是通过由写磁盘程序部份自动计算需要多少磁盘扇区数。
我的一点建议:
课程设计二,有能力同学,在编写程序时,应该考虑一下首先由安装程序计算需要写入到软盘的代码大小,根据代码大小,来决定写入扇区的大小。可以将个这大小存储到名为Fshanqu标号处,可以将这个标号放到了安程程序的开始位置,这样安装程序会将这个大小写入到软盘中,这样从软盘启动时,通过读取它,就可以得到读取多少个扇区到内存中。

另外由于bios只负责读取软盘第一扇区,所以可以设计一个软盘读写子程序Floopy,并写入到软盘的的第一扇区中。这样软盘中第一扇区中的程序,负责把软盘的程序全部读取到内存中后,接着跳转到启动菜单的位置disp加载启动菜单。
cutebe
[第1楼]   [ 回复时间:2013-06-29 20:35 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:0
注册日期:2010-01-27 19:28
很有道理。不知道有没有谁写的代码不超出512B的,或者是经过压缩后代码在一个扇区之内装得下,这样就不用程序自己读取软盘了。
vs9841
[第2楼]   [ 回复时间:2013-07-03 18:49 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29
这个不可能完成的任务。这个程序大小不会低于K级别。关用到那些字符,也够占512B啦。
vs9841
[第3楼]   [ 回复时间:2013-07-03 18:55 ]   [引用]   [回复]   [ top ] 
荣誉值: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
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved