bin2yx 发表于 2017-6-1 18:05:38

课程设计2

很久以前完成的代码。
由于当时水平限制没办法弄成启动盘。所以代码还不完善,但是能在dos下运行,现在也懒得修改了。
写修改时间的代码很困难,windows妈妈不让直接写端口,只能变通处理,幸好能够修改成功。
发上来给后边学习的朋友有困难时看能不能参考一下{:10_254:}

assume cs:code


code segment

setup: mov ax,cs         ;将主程序写入磁盘2扇区
       mov es,ax
          
calc:mov ax,offset zhuc-offset n_in9ok
       mov dx,0
       mov bx,512
       div bx
       cmp dx,0
       jne adal
       jmp short set          
adal:inc al   ;计算出需要的扇区数
          
set:   mov bx,offset zhuc
       mov ah,3   ;写入
           mov ch,0   ;磁道号
           mov cl,2   ;扇区号
           mov dh,0   ;磁头号(面号)
           mov dl,0   ;没有软盘,能否写到81h ;驱动器号(D盘)
           int 13h
          
           mov bx,offset lead;将引导程序写入磁盘1扇区
           mov al,1
           mov ah,3   ;写入
           mov ch,0   ;磁道号
           mov cl,1   ;扇区号
           mov dh,0   ;磁头号(面号)
           mov dl,0   ;没有软盘,能否写到81h ;驱动器号(D盘)
           int 13h
          
lead:mov ax,0      ;程序引导部分 ,负责将主程序写入到引导程序之后的内存
       mov es,ax
       mov ax,offset zhuc-offset n_in9ok ;根据主程序长度计算al
       mov dx,0
       mov bx,512
       div bx
       cmp dx,0
       jne ada2
       jmp short set1          
ada2:inc al

set1:mov bx,offset zhuc-offset lead ;
           add bx,7c00h
       mov ah,2   ;读盘
           mov ch,0   ;磁道号
           mov cl,2   ;扇区号
           mov dh,0   ;磁头号(面号)
           mov dl,0   ;没有软盘,能否用D盘
           int 13h

zhuc:jmp short start          
stack segment
    db 64 dup (0)
stack ends
start:   mov ax,stack
         mov ss,ax
               mov sp,64
               jmp short s

d1 db '1)reset pc',0
d2 db '2)start system',0
d3 db '3)clock',0
d4 db '4)set clock',0
d5 dw x1,x2,x3,x4
d6 db 'Esc)return',0
d7 db 'F1 )change colors',0
d8 db 'time setting error',0
s:       mov ax,cs      ;显示选项
               mov ds,ax
               mov ax,0b800h
               mov es,ax
               mov di,0
               mov cx,2000
sq:               mov byte ptr es:,' '   ;清屏
               inc di
               mov byte ptr es:,7
               inc di
               loop sq
               mov si,offset d1
               mov dh,10
               mov dl,33
               mov bl,7
               call show
               mov si,offset d2
               inc dh
               call show
               mov si,offset d3
               inc dh
               call show
               mov si,offset d4
               inc dh
               call show
               
s1:               mov ah,0   ;等待输入
               int 16h
               cmp al,31h
               jb s1
               cmp al,34h
               ja s1
         mov bl,al ;直接定址
               sub bl,31h
               mov bh,0
               add bx,bx
               jmp cs:d5
               
x1:      mov ax,0ffffh
         push ax
         mov ax,0
         push ax
               mov bp,sp
               jmp dword ptr ss:
               
               
x2:               mov ax,0
         mov es,ax
         mov bx,200h
         mov al,1
             mov ah,2   ;读盘
             mov ch,0   ;磁道号
             mov cl,1   ;扇区号
             mov dh,0   ;磁头号(面号)
             mov dl,80h ;c盘
             int 13h
         push bx
         push es
         mov bx,sp                
             jmp dword ptr ss:

x3:               mov si,offset d3
               mov dh,12
               mov dl,33
               mov bh,0
               mov bl,es:
               or bl,00001000b
               call show; 使第三选项高亮
               mov si,offset d6
               mov dh,1
               mov dl,60
               mov bl,es:
               call show;增加Esc提示
               mov si,offset d7
               inc dh
               call show;增加F1提示
               
x3a:       in al,60h
               cmp al,81h
               je x3b    ;回到初始
               cmp al,3bh
               je x31;跳至变色
               call tm
               mov si,offset td2
               mov dh,24
               mov dl,60
               mov bh,1; bh不等于0时,不设置颜色属性
               call show
               jmp short x3
x3b:   mov al,0
         out 60h,al
         jmp near ptr s

x31:       mov ax,0b800h
               out 60h,al      ;很重要,调零60h端口的数值(这个设置到底有什么用还不太清楚,只知道不设置的话按F1就乱变色)
               mov es,ax
               mov di,1
               mov cx,2000
         cmp byte ptr es:,1
               je x33
x32:   dec byte ptr es:
               add di,2
               loop x32
               jmp near ptr x3a
             
x33:   mov byte ptr es:,7
               add di,2
               loop x33
               jmp near ptr x3a

x4:      mov ax,0
               mov es,ax
               mov di,208h
               push es:
               push es:
               pop es:
               pop es:
               mov word ptr es:,0ffh
               mov word ptr es:,0ffh
               
               mov ax,cs
               mov ds,ax
               mov si,offset n_in9
               mov cx,offset n_in9ok-offset n_in9
         cld                
               rep movsb
               
               cli
               mov word ptr es:,208h
               mov word ptr es:,0
               sti

         mov si,offset d4 ; 修改时间主程序
               mov ax,0b800h
               mov es,ax
               mov dh,13
               mov dl,33
               mov bh,0
               mov bl,es:
               or bl,00001000b
               call show; 使第四选项高亮
               mov byte ptr cs:td2,0
               jmp short x4s
               x4d3 dw tent,tz,ty,tesc,tz,ty
x4s:       call tm;查询时间
x4t:   call tbm ;比对时间,并保存到td3
               mov si,offset td3
               mov dh,24
               mov dl,60
               mov bh,1; bh不等于0时,不设置颜色属性
               call show
               mov di,0f77h;设置查询首地址
               call cw;查亮度所对应的字符串位置(假如没有高亮位设置bl=0),保存到bl(38)
               call zz;BL位时间高亮,自动往后跳过非数字位,保存bl(38)
                  
               mov ax,0
               mov es,ax
               cmp byte ptr es:,0ffh
               jne x4x;数字键程序
               cmp byte ptr es:,0ffh
               jne x4g;功能键程序
               mov bh,1
               jmp short x4t
               
x4x:       mov di,0f77h
         call cw
               call tn
               call ty
               call zz
               mov bh,1
               jmp short x4t   
               
x4g:       mov bl,es:
         add bl,bl
               mov bh,0
               mov byte ptr es:,0ffh
               call x4d3
               mov bh,1
               jmp short x4t

               
tent:       mov ax,0
               mov es,ax
               mov byte ptr es:,0ffh
               push es:
               push es:
               pop es:
               pop es:
               mov al,0
               out 60h,al
               mov ax,0b800h
               mov es,ax
               mov di,1
               mov cx,2000
tenq:       mov byte ptr es:,7
               add di,2
               loop tenq
               jmp near ptr x3
               
tz:               mov di,0f77h
         mov ax,0b800h
               mov es,ax
               call cw
         cmp bx,0
               je tz1
tz2:       sub bx,2
               cmp byte ptr es:,30h
               jb tz2
               cmp byte ptr es:,39h
               jatz2
               call zz
               ret
tz1:       mov bx,36
               call zz
               ret
ty:               mov di,0f77h
         call cw
         cmp bx,36
               je ty1
               add bx,2
               call zz
               ret
ty1:       mov bx,0
               call zz
               ret
               
tesc:       mov ax,0
               mov es,ax
               mov byte ptr es:,0ffh
               push es:
               push es:
               pop es:
               pop es:
               mov al,0
               out 60h,al
               jmp near ptr s

               
tm:             push bx ;查询并保存时间子程序 (直接循环显示时间没法应用中断,应在主程序设置条件循环)
         push si
               push cx
               push ax
             push di
               
               jmp short ti
   td1 db 9,8,7,4,2,0
   td2 db '20yy/mm/dd hh:mm:ss',0,0
       td3 db '20yy/mm/dd hh:mm:ss',0,0
ti:      mov di,0
               mov si,2
               mov cx,6
tii:       push cx
             mov al,cs:td1
               out 70h,al
               in al,71h
               mov ah,al
               mov cl,4
               shr al,cl
               and ah,00001111b
               add ax,3030h
               mov word ptr cs:td2,ax
               cmp byte ptr cs:td2,0
               jne tiii
               mov word ptr cs:td3,ax
tiii:       inc di
               add si,3
               pop cx
               loop tii
               
               pop di
               pop ax
               pop cx
               pop si
               pop bx
             ret
      
tbm:       push bx ;
         push si
               push cx
               push ax
               push di
               
         mov si,18
               
tbii:       mov al,0
               out 70h,al
               in al,71h
               mov ah,al
               mov cl,4
               shr al,cl
               and ah,00001111b
               add ax,3030h
               cmp byte ptr cs:td2,ah
               jne tbiii
               jmp short tbme
               
tbiii:                mov byte ptr cs:td2,1
                  call tm
            cmp td3,39h
                  jne jia
                        mov td3,30h
            dec si
                  cmp td3,35h
                        jne jia
                        mov td3,30h
                        dec si
                        dec si
                        cmp td3,39h
                        jne jia
                        mov td3,30h
                        dec si
                        cmp td3,35h
                        jne jia
                        mov td3,30h
                        dec si
                        dec si
                        cmp word ptr td3,3332h
                        je jia0
                        cmp byte ptr td3,39h
                        jne jia
                        mov td3,30h
                        dec si
                        inc td3
                        jmp short tbme
                       
jia0:       mov word ptr td3,3030h
            call luna
                        jmp short tbme
jia:                inc td3                
               
tbme:       pop di
               pop ax
               pop cx
               pop si
               pop bx
             ret               
               
show:    push ax ; 显示以0结尾的字符串程序 dx=行列 cs:=字符串起点 bl=颜色 bh不等于0时 不设置颜色
               push di
               push cx
               push si
               push dx
               
               mov ax,0b800h
               mov es,ax
               mov ax,160
               mul dh
               add dl,dl
               sub dl,2
               mov dh,0
               add ax,dx
               mov di,ax
sh1:       mov cl,cs:
               jcxz sh2
               mov es:,cl
               inc di
               cmp bh,0
               jne sh_nc
               mov es:,bl
sh_nc:       inc si
               inc di
               jmp short sh1
               
sh2:       pop dx
         pop si
         pop cx
               pop di
               pop ax
         ret

cw:                push ax ; 查亮度子程序(cw),保存至bl?,参数:es: 为查询字符串的首地址
                push es
                push cx
                mov bx,0b800h
                mov es,bx
                mov bx,0
                mov cx,19
               
c1:                mov al,es:
      and al,00001000b
                cmp al,00001000b
                je c2
                add bx,2
                loop c1
                mov bx,0
c2:                pop cx
      pop es
      pop ax
      ret

zz:                push bp   ;高亮时间子程序,bl为高亮位,能自动跳过非数字位。参数:di为时间首地址
      push ax
                push cx
                mov ax,0b800h
                mov es,ax
                mov bp,0
      mov cx,19
z1:   and byte ptr es:,11110111b
                add bp,2
                loop z1               
                cmp byte ptr es:,30h
                jb z3
                cmp byte ptr es:,39h
                ja z3
z2:   or byte ptr es:,00001000b
                pop cx
                pop ax
                pop bp
                ret
z3:                add bx,2
                jmp z2

tn:      push ax ; 时间修改程序
               push bx
               mov bp,sp;保存栈位置
               push word ptr cs:td3
               push word ptr cs:td3
               push word ptr cs:td3
               push word ptr cs:td3
               push word ptr cs:td3
               
               mov ax,bx
         mov bl,2
               div bl
               mov bh,0
               mov bl,al
               mov al,es:
tng:       mov cs:td3,al
          push ax
               push bx
               
               mov bl,10
               mov di,5
               mov cx,5
tngs:       sub word ptr cs:td3,3030h
               add di,3
               loop tngs
               
               mov cx,5
               mov di,5
tngs1:       mov al,td3
               mul bl
               add al,cs:td3
               mov td3,al
               add di,3
               loop tngs1
                              
               mov ax,0b800h
               mov es,ax
               mov di,0e36h
               mov cx,20
tngx:       mov byte ptr es:,' '
               add di,2
               loop tngx
               
               call ttest
               pop bx
         pop ax
               pop word ptr cs:td3
               pop word ptr cs:td3
               pop word ptr cs:td3
               pop word ptr cs:td3
               pop word ptr cs:td3
               mov cs:td3,al
               
tne:       mov ax,0
         mov es,ax
         mov word ptr es:,0ffh
         mov sp,bp
               pop bx
               pop ax
               ret
                              
ttest:       cmp byte ptr cs:td3,12 ;看月份是否大于12
               ja tns
               cmp byte ptr cs:td3,31 ;看日期是否大于31
               ja tns
               cmp byte ptr cs:td3,2 ;看月份是否2月
               je ttest1
               
               mov si,0
               mov cx,4
               jmp short ttxiao
monn db 4,6,9,11
ttxiao:       mov al,cs:monn;看月份是否小月
         cmp byte ptr cs:td3,al
               je ttest2
               add si,2
               loop ttxiao
               
               cmp byte ptr cs:td3,23
               ja tns
               cmp byte ptr cs:td3,59
               ja tns
               cmp byte ptr cs:td3,59
               ja tns
               ret
ttest1:       call runnian
         cmp cs:td3,0    ;看是否闰年
               je ttest1_1
               cmp byte ptr cs:td3,28 ;看日期是否大于28
               ja tns
               ret
ttest1_1: cmp byte ptr cs:td3,29;看日期是否大于29
               ja tns
               ret
ttest2:       cmp byte ptr cs:td3,30 ;看日期是否大于30
               ja tns
               ret
tns:       mov si,offset d8
               mov dh,22
               mov dl,60
               mov bh,1
               call show
         pop ax         ; 多一个Pop 因为是跳到这里来的 栈里存了原ip       
               pop bx
               pop ax
               pop word ptr cs:td3
               pop word ptr cs:td3
               pop word ptr cs:td3
               pop word ptr cs:td3
               pop word ptr cs:td3
               jmp near ptr tne
               
tn1:   push ax ; 时间修改程序
               push bx
               mov ax,bx
         mov bl,2
               div bl
               mov bh,0
               mov bl,al
               mov al,es:
               mov word ptr es:,0ffh
               mov cs:td3,al
               pop bx
               pop ax
               ret
               
luna:    jmp short lunas
mondw 3430h,3630h,3930h,3131h
lunas:       mov cx,4
               mov bp,3133h;设置成31号
               mov si,0
cmp_m:       mov ax,cs:mon
         cmp word ptr cs:td3,ax   ; 看是不是小月
               je xiaoyue
               add si,2
               loop cmp_m
               cmp word ptr cs:td3,3230h; 看是不是2月
               je eryue
         jmp short dayue

xiaoyue: mov bp,3033h         ;设置成30号
         jmp short dayue
               
eryue:   call runnian   ;查是不是闰年,闰年余数保存在cs:td3
         cmp cs:td3,0
               je eryue1
               mov bp,3832h
               jmp short dayue
eryue1:       mov bp,3932h
               
               
dayue:   cmp word ptr cs:td3,bp;看是多少号
         je dayue_1
         cmp byte ptr cs:td3,39h    ;看是不是9号
         je dayue_2
               inc byte ptr cs:td3
               ret
               
dayue_1: mov word ptr cs:td3,3130h;是月底号就改成1号
               cmp word ptr cs:td3,3231h; 看是不是12月
               je dayue12
               cmp byte ptr cs:td3,39h    ; 看是不是9月
               je dayue11
               inc byte ptr cs:td3
               ret
               
dayue_2: inc byte ptr cs:td3       ; 因为前一位不是3,所以是9让前一位加1
               mov byte ptr cs:td3,30h   ; 然后自己变成0
               ret
               
dayue11: mov word ptr cs:td3,3031h;是9月就改成10月
               ret
               
dayue12: mov word ptr cs:td3,3130h ; 是12月就改成1月
               cmp byte ptr cs:td3,39h; 看是不是第9年
               je dayue13
               inc byte ptr cs:td3
               ret
               
dayue13: mov byte ptr cs:td3,30h   ; 是第9年就改成0年
               cmp byte ptr cs:td3,39h   ; 看是不是第9年
               je dayue14
               inc byte ptr cs:td3
               ret
               
dayue14: mov byte ptr cs:td3,30h; 是第9年就改成0年
               cmp byte ptr cs:td3,39h; 看是不是第9年
         je dayue15
               inc byte ptr cs:td3
               ret
               
dayue15: mov byte ptr cs:td3,30h; 是第9年就改成0年
               cmp byte ptr cs:td3,39h; 看是不是第9年
               je dayue16
               inc byte ptr cs:td3
               ret
dayue16: mov byte ptr cs:td3,30h   ; 是第9年就改成0年
               ret
                              
runnian:        push ax   ;闰年查询子程序 ,余数存入cs:td3
            push bx
                        push dx
                        push word ptr cs:td3
                        push word ptr cs:td3
                        sub word ptr cs:td3,3030h
                        sub word ptr cs:td3,3030h
                        mov al,cs:td3
                  mov bl,10
                        mul bl
                        add al,cs:td3
                        mov cs:td3,al   ;46
                        mov cs:td3,0
                        mov al,cs:td3
                        mov bl,100
                        mul bl
                        add word ptr cs:td3,ax
                        mov al,cs:td3
                        mov ah,0
                        mov bx,1000
                        mul bx
                        add ax,word ptr cs:td3
                        mov bx,4
                        mov dx,0
                        div bx
                        mov cs:td3,dl
                        pop word ptr cs:td3
                        pop word ptr cs:td3
                        pop dx
                        pop bx
                        pop ax
                        ret
                       
n_in9:                        ;待安装的int9中断例程 ,功能是比对是否制定的按键,并存入数据段内存的指定区域
         push ax
               push bx
               push cx
               push si
               push di
               
               in al,60h
               pushf
               call dword ptr cs:
               jmp short n
        ind1 db 2,3,4,5,6,7,8,9,0ah,0bh
        ind2 db 1ch,4bh,4dh,1,0eh,0fh
               
n:               mov si,offset ind1-offset n_in9
               mov di,offset ind2-offset n_in9
               mov cx,10
               mov bx,0
n1:               cmp al,cs:
               je in16
               inc bx
               loop n1
               
               mov bx,0
               mov cx,6
n2:               cmp al,cs:
               je gnj
               inc bx
               loop n2
               jmp short n_end ;不是上列按键即返回

in16:    cmp al,0bh
         je in16_2
               add al,2fh
in16_1:mov cs:,al   ;数字键转换ASCII码后存入205
               jmp short n_end
in16_2:       add al,25h
         jmp short in16_1
               
gnj:                     ;功能键参数保存到1
         mov cs:,bl ; (4)位
n_end:       pop di
         pop si
         pop cx
         pop bx
               pop ax
         iret       
               
n_in9ok:               nop


               code ends
               end setup
页: [1]
查看完整版本: 课程设计2