汇编语言实现日历输出

如下汇编代码:输入指定日期打印对应月的日历,怎么修改使输入的日期在日历上以绿色(或其他颜色)显示

DATAS SEGMENT
A1 DB "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$"
A2 DB "*** * *  *   Calendar   *  * * ****$"
A3 DB "designer:B17040605 sxf $"
A4 DB "Please input the date:$"
A5 DB "Please input the date like :20200601$"
A6 DW 0
A7 DB 0
A8 DB "Calendar:$"
A9 DB "-----------------------------------$"
B DW ?        ;两个日期的显示距离
C1 DB 0       ;世纪数
G DB 0        ;G为取出每个月的天数
N DB ?        ;N为每月第一天是星期几
P DW ?        ;P为数值权重
Y DB ?        ; 蔡勒公式里面的y
BUF0 DB 9
DB ?
DB 9 DUP(?)
BUF1 DB 31,?,31,30,31,30,31,31,30,31,30,31
BUF2 DB ' 1$ 2$ 3$ 4$ 5$ 6$ 7$ 8$ 9$10$11$12$13$14$15$16$17$18$19$20$21$22$23$24$25$26$27$28$29$30$31$'
WEEK DB "SUN  MON  TUE  WED  THU  FRI  SAT$"
YEAR DW ?
MONTH DW ?
DAY DW ?
LINE DB 1
WRONG DB "!!! Wrong!Please enter the correct format like :20200601 !!!$"
DATAS ENDS
STACKS SEGMENT
STACKS ENDS
;------------------以下是代码部分-------------------------------
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
;输入界面样式
BEG:
MOV AX,DATAS
MOV DS,AX
MOV AH,0           ;设置显示方式
MOV AL,3           ;80*25彩色文本方式
INT 10H
MOV AH,6
MOV AL,0
MOV CH,0
MOV CL,0 
MOV DH,80
MOV DL,80
MOV BH,01110000B   ;前四位定义背景色为棕色
INT 10H
;显示“~~~~~~~~~~~~~~~~~~~~~~~~~~~~~”
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A1
CALL OUTP
ADD LINE,2
;显示“*** * * *  Calendar   * * * ****”
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A2
CALL OUTP
ADD LINE,2
;显示“designer:B17040605 sxf ”
MOV DH,LINE
MOV DL,8
CALL GUANGBIAO
LEA DX,A3
CALL OUTP
ADD LINE,2
;显示“Please input the date like :20200601”
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A5
CALL OUTP
ADD LINE,2   
;输入日期
INPUT:
MOV AH,6 
MOV AL,0
MOV CH,LINE
MOV CL,23          ;当前行,23列到30列(输入8位字符)
MOV DH,LINE
MOV DL,30
MOV BH,00100001B   ;底色显示为绿色
INT 10H
;显示“Please input the date:”
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A4
CALL OUTP
;把输入的日期保存在缓冲区BUF0中
MOV DH,LINE
MOV DL,23
CALL GUANGBIAO
LEA DX,BUF0 
MOV AH,10
INT 21H
ADD LINE,1
;ASCII码转真值
LEA DI,BUF0+2            ;DI指向日期输入串的首地址
MOV CX,4
MOV AX,0
P1: MOV BL,[DI]          ;取字符送到BL
SUB BL,30H               ;字符减去30H,转化为真值
MOV BH,0 
MOV P,10
MUL P
ADD AX,BX
INC DI                   ;DI指向下一个字符
DEC CX                   ;长度减一
JNZ P1
MOV YEAR,AX              ;获得年份值
CALL PDRN                ;调用判断平年还是闰年的程序
JC L1                    ;有进位,借位,跳转到L1,输出闰年;否则顺序执行,是平年
LEA DI,BUF1
MOV [DI+1],BYTE PTR 28   ;平年把28送入BUF1中
JMP L2
L1:
LEA DI,BUF1
MOV [DI+1],BYTE PTR 29   ;闰年把29送入BUF1中
L2:
LEA DI,BUF0+6
MOV CL,2
MOV AX,0
P2: MOV BL,[DI]          ;取字符送到BL
SUB BL,30H               ;字符减去30H,转化为真值
MOV BH,0
MOV P,10
MUL P
ADD AX,BX
INC DI
DEC CX                   ;长度减一
JNZ P2
MOV MONTH,AX             ;获得月份值
LEA DI,BUF0+8
MOV CL,2
MOV AX,0
P3: MOV BL,[DI]          ;取字符送到BL
SUB BL,30H               ;字符减去30H,转化为真值
MOV BH,0
MOV P,10
MUL P
ADD AX,BX
INC DI
DEC CX                  ;长度减一
JNZ P3
MOV DAY,AX              ;获得日值
CMP MONTH,1             ;月份<1?报错
JC ERROR
CMP MONTH,13            ;月份>12,报错
JNC ERROR
CMP DAY,1
JC ERROR
CALL PDXQJ              ;显示日历,调用PDXQJ子程序返回N的值,N为每月第一天是星期几
MOV DI,OFFSET BUF1
DEC MONTH               ;PDXQJ中MONTH加了1
DEC MONTH               ;偏移值
ADD DI,MONTH            ;取出当月的天数
MOV CL,[DI]
MOV G,CL                ;取出每个月的天数为G
CMP BYTE PTR DAY,CL     ;输入的天如果超过这个月的最大天数就报错
JA ERROR
;显示“~~~~~~~~~~~~~~~~~~~~~~~~~~”
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A1
CALL OUTP
ADD LINE,2
;显示“Calendar:XXXX.XX.XX”
MOV DH,LINE
MOV DL,7
CALL GUANGBIAO
LEA DX,A8
CALL OUTP
MOV DH,LINE
MOV CL,8
MOV DL,16
CALL GUANGBIAO
LEA DI,BUF0+2
MOV AX,0
;显示“---------------------------”
ADD LINE,1
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A9
CALL OUTP
ADD LINE,2
;显示“SUN  MON  TUE  WED  THU  FRI  SAT”
MOV DH,LINE
MOV DL,0
CALL GUANGBIAO
LEA DX,WEEK
CALL OUTP 
INC LINE
MOV SI,OFFSET BUF2
MOV AL,5
MUL N               ;N为每月第一天是星期几
MOV B,AX            ;5*N
CMP B,35            ;B<35,执行POS  ,如果每个月一号是星期天,显示一号的行号减1
JC POS
SUB LINE,1
;周日设置红色显示0~3
POS:
MOV DH,LINE         ;每个月的一号的光标位置
MOV DL,BYTE PTR B   ;B=5*N
CALL GUANGBIAO
MOV A7,31
CMP DL,A7
JBE POS1            ;DL<=31(星期六),跳转到POS1,否则行加1,列从0开始
ADD LINE,1          ;两行日期间隔
MOV AX,0
MOV B,AX
MOV AH,6 
MOV AL,0
MOV CH,LINE
MOV CL,0
MOV DH,LINE
MOV DL,3
MOV BH,00110100B
INT 10H
JMP POS
;周六的日历显示红色30~33
POS1: 
CMP DL,30           ;不是星期六也不是星期天,不用红色
JC NORED 
MOV AH,6
MOV AL,0
MOV CH,LINE
MOV CL,30
MOV DH,LINE
MOV DL,33
MOV BH,00110100B
INT 10H
;打印日历
NORED: 
MOV DX,SI
CALL OUTP          ;在当前光标位置显示数字
ADD SI,3
ADD B,5            ;每两个日期的显示距离5
DEC G              ;G为取出每个月的天数
JNZ POS
MOV AH,7           ;无回显键盘输入
INT 21H
MOV BL,1
MOV LINE,BL
JMP BEG
;显示错误提示信息
ERROR:
MOV AH,6 
MOV AL,0
MOV CH,LINE
MOV CL,0           ;当前行,23列到30列(输入8位字符)
MOV DH,LINE
MOV DL,60
MOV BH,01000001B   ;底色显示为红色
INT 10H
MOV DL,1
CALL GUANGBIAO
LEA DX,WRONG
CALL OUTP
INC LINE
JMP INPUT
EXIT: MOV AH,4CH
INT 21H
;光标的函数GUANGBIAO
GUANGBIAO PROC
PUSH AX
PUSH BX
MOV AH,2          ;2号功能调用,预置光标的位置
MOV BH,0
INT 10H           ;定光标
POP BX
POP AX
RET
GUANGBIAO ENDP
;显示输出的函数OUTP
OUTP PROC
PUSH AX
MOV AH,9          ;9号功能调用,字符串输出
INT 21H
POP AX
RET
OUTP ENDP
;判断是平年还是闰年的程序PDRN
PDRN PROC 
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX,YEAR
MOV CX,AX
MOV DX,0           ;DX=0
MOV BX,4
DIV BX             ;AX/4
CMP DX,0           ;DX中为余数,与0比较
JNZ B1
MOV AX,CX
MOV BX,100
DIV BX             ;AX/100
CMP DX,0
JNZ B2
MOV AX,CX
MOV BX,400
DIV BX             ;AX/400
CMP DX,0
JZ B2
B1: CLC            ;CF=0
JMP B3
B2: STC            ;CF=1
B3: POP DX
POP CX
POP BX
POP AX
RET
PDRN ENDP
;利用蔡勒公式获得这个月的一号是星期几
PDXQJ PROC         ;保护现场
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BL,100
MOV AX,YEAR        ;年份给AX
DIV BL
MOV C1,AL
MOV Y,AH
MOV CL,2
MOV BL,C1
SHR BL,CL          ;int(c/4)
SHL C1,1            ;2*c
SUB BL,C1
ADD BL,Y
SHR Y,CL            ;int(y/4)
ADD BL,Y           ;int(c/4)-2*c+y+int(y/4)
INC MONTH
CMP MONTH,3        ;是一月?转移
JC J1 
CMP MONTH,4        ;是二月?转移
JC J1
XOR AH,AH
MOV AX,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            ;计算出来的结果模取7
CMP AH,0
JG SKIPADD
ADD AH,7
SKIPADD:
MOV BL,AH
MOV N,BL
JMP J3              ;还原现场
;J1处理:所以要判断如果输入的年后两位是00的时候计数时将年用99进行替代。
J1: MOV BL,100
MOV AX,YEAR
DIV BL
MOV C1,AL
MOV Y,AH
CMP Y,1             ;如果年份后两位是00,则前一年是99
JNC J2
ADD Y,100
;J2:1月和2月按上一年的13月和14月来算这时C和y均按上一年取值。
J2: SUB Y,1
MOV CL,2
MOV BL,C1
SHR BL,CL          ;int(c/4)
SHL C1,1            ;2*c
SUB BL,C1
ADD BL,Y
SHR Y,CL
ADD BL,Y
ADD MONTH,12
XOR AH,AH
MOV AX,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             ;计算出来的结果模取7
IDIV CL
CMP AH,0             ;AH > 0 跳转
JG ADD1
ADD AH,7             ;星期天N为7
ADD1:
MOV BL,AH
MOV N,BL
SUB MONTH,12        ;还原月份值
J3: POP DX
POP CX
POP BX
POP AX
RET
PDXQJ ENDP
CODES ENDS
END START

要实现输入的日期在日历上以绿色显示,可以在打印日历的部分加入判断语句:

1、在每次打印一个日期时,判断当前日期是否等于输入的日期;
2、如果相等,则设置字体的颜色为绿色(或者其他颜色)。
以下是代码修改的部分:
1、在数据段中添加绿色颜色定义:

GREEN DB 00100010B

2、在打印日历的部分,加入判断和设置颜色的语句:

MOV AH,6
MOV AL,0
MOV CH,LINE
MOV CL,B
MOV DH,LINE
CMP A7,CL          ; A7 为当前日期
JE GREEN_COLOR     ; 判断是否等于输入的日期
ADD DL,3
JMP SET_COLOR      ; 设置颜色
GREEN_COLOR:
MOV DH,GREEN       ; 设置绿色
MOV DL,BYTE PTR GREEN+1
SET_COLOR:
INT 10H
ADD B,3            ; 每两个日期的间隔距离为3

可以借鉴下

DATAS SEGMENT
A1 DB "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$"
A2 DB "*** * *  *   Calendar   *  * * ****$"
A3 DB "designer:B17040605 sxf $"
A4 DB "Please input the date:$"
A5 DB "Please input the date like :20200601$"
A6 DW 0
A7 DB 0
A8 DB "Calendar:$"
A9 DB "-----------------------------------$"
B DW ?        ;两个日期的显示距离
C1 DB 0       ;世纪数
G DB 0        ;G为取出每个月的天数
N DB ?        ;N为每月第一天是星期几
P DW ?        ;P为数值权重
Y DB ?        ; 蔡勒公式里面的y
BUF0 DB 9
DB ?
DB 9 DUP(?)
BUF1 DB 31,?,31,30,31,30,31,31,30,31,30,31
BUF2 DB ' 1$ 2$ 3$ 4$ 5$ 6$ 7$ 8$ 9$10$11$12$13$14$15$
16$17$18$19$20$21$22$23$24$25$26$27$28$29$30$31$'
WEEK DB "SUN  MON  TUE  WED  THU  FRI  SAT$"
YEAR DW ?
MONTH DW ?
DAY DW ?
LINE DB 1
WRONG DB "!!! Wrong!Please enter the correct format like :20200601 !!!$"
DATAS ENDS
STACKS SEGMENT
STACKS ENDS
;------------------以下是代码部分-------------------------------
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
;输入界面样式
BEG:
MOV AX,DATAS
MOV DS,AX
MOV AH,0           ;设置显示方式
MOV AL,3           ;80*25彩色文本方式
INT 10H
MOV AH,6
MOV AL,0
MOV CH,0
MOV CL,0 
MOV DH,80
MOV DL,80
MOV BH,01110000B   ;前四位定义背景色为棕色
INT 10H
;显示“~~~~~~~~~~~~~~~~~~~~~~~~~~~~~”
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A1
CALL OUTP
ADD LINE,2
;显示“*** * * *  Calendar   * * * ****”
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A2
CALL OUTP
ADD LINE,2
;显示“designer:B17040605 sxf ”
MOV DH,LINE
MOV DL,8
CALL GUANGBIAO
LEA DX,A3
CALL OUTP
ADD LINE,2
;显示“Please input the date like :20200601”
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A5
CALL OUTP
ADD LINE,2   
;输入日期
INPUT:
MOV AH,6 
MOV AL,0
MOV CH,LINE
MOV CL,23          ;当前行,23列到30列(输入8位字符)
MOV DH,LINE
MOV DL,30
MOV BH,00100001B   ;底色显示为绿色
INT 10H
;显示“Please input the date:”
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A4
CALL OUTP
;把输入的日期保存在缓冲区BUF0中
MOV DH,LINE
MOV DL,23
CALL GUANGBIAO
LEA DX,BUF0 
MOV AH,10
INT 21H
ADD LINE,1
;ASCII码转真值
LEA DI,BUF0+2            ;DI指向日期输入串的首地址
MOV CX,4
MOV AX,0
P1: MOV BL,[DI]          ;取字符送到BL
SUB BL,30H               ;字符减去30H,转化为真值
MOV BH,0 
MOV P,10
MUL P
ADD AX,BX
INC DI                   ;DI指向下一个字符
DEC CX                   ;长度减一
JNZ P1
MOV YEAR,AX              ;获得年份值
CALL PDRN                ;调用判断平年还是闰年的程序
JC L1                    ;有进位,借位,跳转到L1,输出闰年;否则顺序执行,是平年
LEA DI,BUF1
MOV [DI+1],BYTE PTR 28   ;平年把28送入BUF1中
JMP L2
L1:
LEA DI,BUF1
MOV [DI+1],BYTE PTR 29   ;闰年把29送入BUF1中
L2:
LEA DI,BUF0+6
MOV CL,2
MOV AX,0
P2: MOV BL,[DI]          ;取字符送到BL
SUB BL,30H               ;字符减去30H,转化为真值
MOV BH,0
MOV P,10
MUL P
ADD AX,BX
INC DI
DEC CX                   ;长度减一
JNZ P2
MOV MONTH,AX             ;获得月份值
LEA DI,BUF0+8
MOV CL,2
MOV AX,0
P3: MOV BL,[DI]          ;取字符送到BL
SUB BL,30H               ;字符减去30H,转化为真值
MOV BH,0
MOV P,10
MUL P
ADD AX,BX
INC DI
DEC CX                  ;长度减一
JNZ P3
MOV DAY,AX              ;获得日值
CMP MONTH,1             ;月份<1?报错
JC ERROR
CMP MONTH,13            ;月份>12,报错
JNC ERROR
CMP DAY,1
JC ERROR
CALL PDXQJ              ;显示日历,调用PDXQJ子程序返回N的值,N为每月第一天是星期几
MOV DI,OFFSET BUF1
DEC MONTH               ;PDXQJ中MONTH加了1
DEC MONTH               ;偏移值
ADD DI,MONTH            ;取出当月的天数
MOV CL,[DI]
MOV G,CL                ;取出每个月的天数为G
CMP BYTE PTR DAY,CL     ;输入的天如果超过这个月的最大天数就报错
JA ERROR
;显示“~~~~~~~~~~~~~~~~~~~~~~~~~~”
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A1
CALL OUTP
ADD LINE,2
;显示“Calendar:XXXX.XX.XX”
MOV DH,LINE
MOV DL,7
CALL GUANGBIAO
LEA DX,A8
CALL OUTP
MOV DH,LINE
MOV CL,8
MOV DL,16
CALL GUANGBIAO
LEA DI,BUF0+2
MOV AX,0
;显示“---------------------------”
ADD LINE,1
MOV DH,LINE
MOV DL,1
CALL GUANGBIAO
LEA DX,A9
CALL OUTP
ADD LINE,2
;显示“SUN  MON  TUE  WED  THU  FRI  SAT”
MOV DH,LINE
MOV DL,0
CALL GUANGBIAO
LEA DX,WEEK
CALL OUTP 
INC LINE
MOV SI,OFFSET BUF2
MOV AL,5
MUL N               ;N为每月第一天是星期几
MOV B,AX            ;5*N
CMP B,35            ;B<35,执行POS  ,如果每个月一号是星期天,显示一号的行号减1
JC POS
SUB LINE,1
;周日设置红色显示0~3
POS:
MOV DH,LINE         ;每个月的一号的光标位置
MOV DL,BYTE PTR B   ;B=5*N
CALL GUANGBIAO
MOV A7,31
CMP DL,A7
JBE POS1            ;DL<=31(星期六),跳转到POS1,否则行加1,列从0开始
ADD LINE,1          ;两行日期间隔
MOV AX,0
MOV B,AX
MOV AH,6 
MOV AL,0
MOV CH,LINE
MOV CL,0
MOV DH,LINE
MOV DL,3
MOV BH,00110100B
INT 10H
JMP POS
;周六的日历显示红色30~33
POS1: 
CMP DL,30           ;不是星期六也不是星期天,不用红色
JC NORED 
MOV AH,6
MOV AL,0
MOV CH,LINE
MOV CL,30
MOV DH,LINE
MOV DL,33
MOV BH,00110100B
INT 10H
;打印日历
NORED: 
MOV DX,SI
CALL OUTP          ;在当前光标位置显示数字
ADD SI,3
ADD B,5            ;每两个日期的显示距离5
DEC G              ;G为取出每个月的天数
JNZ POS
MOV AH,7           ;无回显键盘输入
INT 21H
MOV BL,1
MOV LINE,BL
JMP BEG
;显示错误提示信息
ERROR:
MOV AH,6 
MOV AL,0
MOV CH,LINE
MOV CL,0           ;当前行,23列到30列(输入8位字符)
MOV DH,LINE
MOV DL,60
MOV BH,01000001B   ;底色显示为红色
INT 10H
MOV DL,1
CALL GUANGBIAO
LEA DX,WRONG
CALL OUTP
INC LINE
JMP INPUT
EXIT: MOV AH,4CH
INT 21H
;光标的函数GUANGBIAO
GUANGBIAO PROC
PUSH AX
PUSH BX
MOV AH,2          ;2号功能调用,预置光标的位置
MOV BH,0
INT 10H           ;定光标
POP BX
POP AX
RET
GUANGBIAO ENDP
;显示输出的函数OUTP
OUTP PROC
PUSH AX
MOV AH,9          ;9号功能调用,字符串输出
INT 21H
POP AX
RET
OUTP ENDP
;判断是平年还是闰年的程序PDRN
PDRN PROC 
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX,YEAR
MOV CX,AX
MOV DX,0           ;DX=0
MOV BX,4
DIV BX             ;AX/4
CMP DX,0           ;DX中为余数,与0比较
JNZ B1
MOV AX,CX
MOV BX,100
DIV BX             ;AX/100
CMP DX,0
JNZ B2
MOV AX,CX
MOV BX,400
DIV BX             ;AX/400
CMP DX,0
JZ B2
B1: CLC            ;CF=0
JMP B3
B2: STC            ;CF=1
B3: POP DX
POP CX
POP BX
POP AX
RET
PDRN ENDP
;利用蔡勒公式获得这个月的一号是星期几
PDXQJ PROC         ;保护现场
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BL,100
MOV AX,YEAR        ;年份给AX
DIV BL
MOV C1,AL
MOV Y,AH
MOV CL,2
MOV BL,C1
SHR BL,CL          ;int(c/4)
SHL C1,1            ;2*c
SUB BL,C1
ADD BL,Y
SHR Y,CL            ;int(y/4)
ADD BL,Y           ;int(c/4)-2*c+y+int(y/4)
INC MONTH
CMP MONTH,3        ;是一月?转移
JC J1 
CMP MONTH,4        ;是二月?转移
JC J1
XOR AH,AH
MOV AX,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            ;计算出来的结果模取7
CMP AH,0
JG SKIPADD
ADD AH,7
SKIPADD:
MOV BL,AH
MOV N,BL
JMP J3              ;还原现场
;J1处理:所以要判断如果输入的年后两位是00的时候计数时将年用99进行替代。
J1: MOV BL,100
MOV AX,YEAR
DIV BL
MOV C1,AL
MOV Y,AH
CMP Y,1             ;如果年份后两位是00,则前一年是99
JNC J2
ADD Y,100
;J2:1月和2月按上一年的13月和14月来算这时C和y均按上一年取值。
J2: SUB Y,1
MOV CL,2
MOV BL,C1
SHR BL,CL          ;int(c/4)
SHL C1,1            ;2*c
SUB BL,C1
ADD BL,Y
SHR Y,CL
ADD BL,Y
ADD MONTH,12
XOR AH,AH
MOV AX,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             ;计算出来的结果模取7
IDIV CL
CMP AH,0             ;AH > 0 跳转
JG ADD1
ADD AH,7             ;星期天N为7
ADD1:
MOV BL,AH
MOV N,BL
SUB MONTH,12        ;还原月份值
J3: POP DX
POP CX
POP BX
POP AX
RET
PDXQJ ENDP
CODES ENDS
END START

基于GPT4和Treabhar的编写:
要使输入的日期在日历上以绿色(或其他颜色)显示,需要修改相应的代码部分。

在输入界面样式的部分,找到以下代码:

MOV AH,6
MOV AL,0
MOV CH,LINE
MOV CL,23          ;当前行,23列到30列(输入8位字符)
MOV DH,LINE
MOV DL,30
MOV BH,00100001B   ;底色显示为绿色
INT 10H

将其中的 BH 寄存器的值改为你想要的颜色代码,例如 00100010B 表示底色为红色,00100011B 表示底色为蓝色,你可以根据需要选择合适的颜色代码。

另外,在日历打印部分,找到以下代码:

MOV AH,6
MOV AL,0
MOV CH,LINE
MOV CL,30
MOV DH,LINE
MOV DL,33
MOV BH,00110100B
INT 10H

将其中的 BH 寄存器的值改为你想要的颜色代码,同样可以根据需要选择合适的颜色。

请注意,具体的颜色代码取决于你所使用的显示设备和支持的颜色模式。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
要实现输入的日期在日历上以绿色显示,需要在日历打印的过程中找到输入日期在日历中对应的位置,再改变输出时的颜色属性,可以在显示日历的部分代码中进行修改。

以下是修改部分的代码片段(已在原代码中注释):

MOV DX,SI
CALL OUTP ;在当前光标位置显示数字
ADD SI,3
ADD B,5 ;每两个日期的显示距离5
DEC G ;G为取出每个月的天数
;在这里添加修改颜色的代码
CMP AX,DAY ;如果当前打印的日期等于输入的日期
JE GREEN ;跳转改变颜色
JNZ POS ;否则继续正常输出
GREEN:
MOV AH,6
MOV AL,0
MOV CH,LINE
MOV DL,B ;当前光标所在列位置
MOV DH,LINE
MOV BH,00101010B ;改变前景色为绿色
INT 10H
JMP POS ;跳转继续输出

以下是完整代码:
如果我的回答解决了您的问题,请采纳!

参考GPT和自己的思路:需要修改的部分是输出日期时的底色,可以将相应的 INT 10H 中的 BH 寄存器的值修改为其他代表颜色的二进制数值,比如绿色为 00010001B。具体修改代码如下:

在INPUT标签下方加入以下代码:

MOV AH,6
MOV AL,0
MOV CH,LINE
MOV CL,0 
MOV DH,LINE
MOV DL,10
MOV BH,00010001B   ;底色显示为绿色
INT 10H

其中,BH 寄存器的二进制数值 00010001B 表示绿色。可以根据需求修改其他颜色的数值。

以下答案由GPT-4.5Plus大模型(语音)与博主A努力中.......共同编写:

可以这样修改:

  1. 定义两个标志变量:
assembly
flag DB ?        ;标志输入日期是否找到
color DB 0       ;颜色值

  1. 在循环打印日历时,判断当前打印的日期是否是输入的日期:
assembly
CMP DAY,BYTE PTR [SI]     ;当前打印的日期等于输入的日期吗?
JZ FOUND                   ;找到,跳转

  1. 如果找到,设置标志和要打印的颜色,然后继续打印:
assembly 
FOUND:
MOV flag,1                ;找到,设置标志
MOV color,2                ;设置打印颜色为绿色
MOV AH,6
MOV AL,0
MOV CH,LINE
MOV CL,B                    ;从位置B开始
MOV DH,LINE
ADD DL,1                    ;打印一个字符
MOV BH,color             ;设置背景色为绿色
INT 10H
ADD B,1                    ;字符位置加1     

  1. 如果没有找到,正常打印并增加位置:
assembly
NOFIND:  
MOV AH,6
MOV AL,0
MOV CH,LINE  
MOV CL,B
MOV DH,LINE
ADD DL,1  
MOV BH,01000001B   ;默认背景色        
INT 10H 
ADD B,1

  1. 在循环结束后,判断标志,如果没找到输入的日期,提示错误:
assembly
CMP flag,1          ;找到了输入的日期吗?
JE ENDP              ;找到,退出程序
ERRORINPUT:          ;没有找到,提示错误
LEA DX,ERRORINPUTMSG
CALL OUTP
JMP INPUT            ;重新输入

这样就实现了在日历上以指定颜色高亮显示输入的日期。