汇编语言课程设计(原程序)

;月历打印
;主程序设置好入口参数,BX=年份,DL=月份
;调用子模块 display
;Made by wangrui
;2006-12-8

extrn  display:far

Esccode   equ   01h
Up    equ 048h
Down  equ  050h
Left  equ  04bh
Right equ  04dh

dseg segment
 Year     dw 0
 Month    db 0
 temp     db 10 dup(0)
 count  dw ?
 ErrMsg   db 0dh,0ah,"The input NOT decimal! $"
dseg ends

cseg segment
 assume cs:cseg,ds:dseg
start:
 mov ax,dseg
 mov ds,ax

 call GetYearMonth

Ws: 
 

 mov bx,Year
 mov dl,Month
 call far ptr display
again:
 mov ah,0
 int 16h
 cmp ah,Esccode
 je  Exit
 cmp ah,Up
 je  NextY
 cmp ah,Down
 je  PreY
 cmp ah,Left
 je  PreM
 cmp ah,Right
 je  NextM
 jmp again

NextY:
 inc Year
 jmp Ws
PreY:
 dec Year
 jmp Ws
NextM:
 inc Month
 cmp Month,12
 jbe  skip0
 mov Month,1
 inc Year
skip0:
 jmp Ws
PreM:
 dec Month
 cmp Month,1
 jae skip1
 mov Month,12
 dec Year
skip1:
 jmp Ws

Exit:
 mov ah,4ch
 int 21h

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

GetYearMonth  proc  near
 push ax
 push cx
 push si
 push di

inputagain:
 mov Year,0
 mov Month,0

 mov  si,0
repeatY:
 mov  ah,1
 int  21h
 cmp  al,0dh
 je   EndY
 cmp  al,20h
 je   EndY
 cmp  al,1bh
 je   ExitDos0
 cmp  al,30h
 jb   Err
 cmp  al,39h
 ja   Err
 sub  al,30h
 mov  temp[si],al
 inc  si
 jmp  repeatY

Err:
 mov ah,9
 lea dx,ErrMsg
 int 21h
 mov ah,2
 mov dl,0dh
 int 21h
 mov dl,0ah
 int 21h
 jmp inputagain

EndY:
 mov bx,10
 mov di,si
 mov si,0

NextYBit:
 mov ah,0
 mov al,temp[si]
 mov count,di
 sub count,si
 dec count
 mov cx,count
 jcxz skipY
lopmul: mul bx
 loop lopmul
skipY: add Year,ax
 inc si
 cmp si,di
 jne NextYBit
 
;----------------------------------The year is put into [Year]

 push dx
 mov ah,2
 mov dl,0dh
 int 21h
 mov dl,0ah
 int 21h
 pop dx
 jmp skiplap

ExitDos0:
 jmp ExitDos

skiplap:
 mov  si,0
repeatM:
 mov  ah,1
 int  21h
 cmp  al,0dh
 je   EndMon
 cmp  al,20h
 je   EndMon
 cmp  al,1bh
 je   ExitDos
 cmp  al,30h
 jb   Err
 cmp  al,39h
 ja   Err
 sub  al,30h
 mov  temp[si],al
 inc  si
 jmp  repeatM

EndMon: 
 mov  di,si
 mov  si,0
 mov  bl,10
NextMBit:
 mov  al,temp[si]
 mov count,di
 sub count,si
 dec count
 mov cx,count
 jcxz skipM
lpmul: mul  bl
 loop lpmul
skipM: add  Month,al
 inc  si
 cmp  si,di
 jne NextMBit

;-------------------------The Month is put into [Month]

 push dx
 mov ah,2
 mov dl,0dh
 int 21h
 mov dl,0ah
 int 21h
 pop dx

 pop  di
 pop  si
 pop  cx
 pop  ax
 ret
ExitDos:
 mov ah,4ch
 int 21h
GetYearMonth endp

cseg ends
 end start 

 

;display模块

;***********************************
;入口参数:bx = Year dl=Month
;***********************************

public display
data segment
 Year    dw  ?
 Month  db  ?
 leap db  ?
 weekstr db  "  MON  TUR  WEN  THU  FRI  SAT  SUN",'$'
 fillblank db "     $"
 fillblank4 db "    $"
 fillblank3 db "   $"
 c      db  ?
 y    db  ?
 firstday db ?
 temp  db  ?
 MonthSize db ?
data ends

cseg segment
 assume cs:cseg,ds:data
display proc far
 push ds

 mov ax,data
 mov ds,ax

 mov Year,bx
 mov Month,dl

 mov dx,0
 xor bh,bh
 mov ah,2
 int 10h

 mov ah,6
 mov al,0
 mov bh,01110000b
 mov ch,0
 mov cl,0
 mov dh,24
 mov dl,79
 int 10h

 mov ah,6
 mov al,0
 mov bh,01110100b
 mov ch,0
 mov cl,25
 mov dh,24
 mov dl,79
 int 10h

 call far ptr dispYM
 
 lea dx,weekstr
 mov ah,9
 int 21h
 mov ah,2
 mov dl,0dh
 int 21h
 mov dl,0ah
 int 21h

 call GetMonthSize ;把当前月份的天数放到MonthSize

 cmp Month,2
 ja  skip
 add Month,12
 dec Year
skip:
 mov bl,100
 mov ax,Year
 div bl
 mov c,al
 mov y,ah
 mov cl,2
 mov bl,c
 shr bl,cl ;int(c/4)
 shl c,1  ;2*c
 sub bl,c 
 add bl,y
 shr y,cl ;int(y/4)
 add bl,y ;int(c/4)-2*c+y+int(y/4)--->bl
 inc Month
 xor ah,ah
 mov al,Month
 mov dx,13
 mul dx
 mov cx,5
 div cx
 xchg ax,bx
 cbw
 xchg ax,bx
 add bx,ax ;int(c/4)-2*c+y+int(y/4)+int(13*(m+1)/5)
 mov ax,bx
 mov cl,7
 idiv cl
 cmp ah,0
 jG  skipAdd
 add ah,7
skipAdd:
 mov bl,ah
 mov firstday,bl

;--------------------------------计算出当前月份的第一天是星期几

 mov cl,bl
 mov ch,0
 dec cl
 jcxz skipF
FillB: mov ah,9
 lea dx,fillblank
 int 21h
 loop FillB
skipF:
 mov cl,1
disLop: call dispWeek  ;日期已经放入cl
 inc cl
 inc bl
 cmp bl,8
 jb  skipModle
 
 mov bl,1
 mov ah,2
 mov dl,0dh
 int 21h
 mov dl,0ah
 int 21h

skipModle:
 cmp cl,MonthSize
 jbe dislop
 
 mov ah,2
 mov dl,0dh
 int 21h
 mov dl,0ah
 int 21h

 pop ds
 ret
display endp

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

GetMonthSize proc near
 push ax
 push dx

 mov leap,0
 mov ax,Year
 mov ch,00000011b
 and ch,al
 mov bl,100
 div bl
 mov cl,ah
 cmp ch,0
 jne skipNLeap
 cmp cl,0
 jne skipLeap

 mov ax,Year
 mov bx,400
 mov dx,0
 div bx
 cmp dl,0
 je  skipLeap
skipNLeap:
 jmp gmsize
skipLeap:
 inc leap
gmsize:
 mov al,Month
 cmp al,2
 je  return2
 cmp al,8
 jb  skipInc
 inc al
skipInc:
 test al,1
 jz   returnEven
 mov MonthSize,31
 jmp return
returnEven:
 mov MonthSize,30
 jmp return

return2:
 mov MonthSize,28
 cmp leap,0
 je  return
 inc MonthSize
return: 
 pop  dx
 pop  bx
 ret
GetMonthSize endp

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

dispWeek proc  near
 push cx
 push bx
 push ax
 push dx

 cmp cl,10
 jae DoubleDig

 lea dx,fillblank4
 mov ah,9
 int 21h
 mov dl,cl
 add dl,30h
 mov ah,2
 int 21h
 jmp back
 
DoubleDig:
 mov ch,10
 mov ah,0
 mov al,cl
 div ch

 mov cx,ax
 mov ah,9
 lea dx,fillblank3
 int 21h
 mov dl,cl
 add dl,30h
 mov ah,2
 int 21h
 mov dl,ch
 add dl,30h
 int 21h
back:
 pop  dx
 pop  ax
 pop  bx
 pop  cx
 ret
dispWeek endp
;*********************************************************

dispYM proc  far
 push bx
 push dx

 mov ax,year
 mov dh,10
 xor si,si
next: div dh
 mov cl,ah
 mov ch,0
 inc si
 push cx
 mov ah,0
 cmp ax,0
 jne next

 mov cx,si
repeat: pop dx
 mov ah,2
 add dl,30h
 int 21h
 loop repeat

 mov dl,0dh
 mov ah,2
 int 21h
 mov dl,0ah
 mov ah,2
 int 21h

 mov al,Month
 mov ah,0
 mov bl,10
 div bl
 mov cx,ax
 mov dl,cl
 mov ah,2
 add dl,30h
 int 21h
 mov dl,ch
 add dl,30h
 int 21h

 mov dl,0dh
 mov ah,2
 int 21h
 mov dl,0ah
 mov ah,2
 int 21h

 pop dx
 pop bx
 ret
dispYM endp
;******************************************************

cseg ends
 end

你可能感兴趣的:(汇编语言课程设计(原程序))