📄 程序.txt
字号:
.model small
.stack
.data
led db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh ;段码
buf db 3,0
;存放要显示的十位和个位
intseg dw ? ;存放段地址
intoff dw ? ;存放偏移地址
intimr db ?
.code
.startup
start:
mov dx,28bh ;将8255设为A和C口输出
mov al,80h
out dx,al
mov al,0 ;关数码管显示
mov dx,28ah ;设置C口为0
out dx,al
mov ax,350bh ;原中断向量保存
int 21h
mov intseg,es
mov intoff,bx
cli ;关中断
push ds
mov dx,offset new0bh ;修改0bh号中断的服务程序为newobh
mov ax,seg new0bh
mov ds,ax
mov ax,250bh
int 21h
pop ds
in al,21h ;读出IMR
mov intimr,al ;保存原IMR内容
and al,0f7h ;允许IRQ3中断请求
out 21h,al ;设置新IMR内容
mov dx,283h ;向8253控制端口写控制字
mov al,36h ;使计数器0为工作方式3
out dx,al
mov ax,1000 ;写入循环计数初值1000
mov dx,280h
out dx,al ;先写低字节
mov al,ah
out dx,al ;后写高字节
;
mov dx,283h
mov al,76h ;使计数器1工作方式3
out dx,al
mov ax,1000 ;写入循环计数初值1000
mov dx,281h
out dx,al ;写低字节
mov al,ah
out dx,al ;写高字节
;
mov dx,28ah ;dx中存C口地址
sti ;开中断
again:
mov ah,3 ;赋数码管初值为30秒
mov buf,ah
mov ah,0
mov buf+1,ah
in al,dx
and al,3
or al,00110000b ;初始化南北绿灯亮,东西红灯亮
out dx,al
again1:
call displayy ;数码管显示
mov ah,buf
mov al,buf+1
cmp ax,0 ;判断数码管显示是否为零
jne again1 ;不是零继续显示
in al,dx
and al,11011111b ;使南北绿灯灭
out dx,al
mov ah,0 ;赋数码管初值为5秒
mov buf,ah
mov ah,5
mov buf+1,ah
yellow: ;黄灯闪烁程序
mov cx,30 ;设置循环次数
cx0:
cmp cx,0
jne cxNot0 ;cx不是0继续显示
in al,dx
xor al,01000000b ;改变黄灯状态
out dx,al
jmp Time0
cxNot0:
call displayy ;数码管显示
dec cx ;cx减1
call delayMs ;延时
jmp cx0
Time0:
mov ah,buf ;判断黄灯闪烁时间是否结束
mov al,buf+1
cmp ax,0
jne yellow ;时间不是0继续闪烁
jmp again12
AGAIN11:
jmp again ;跳转中继,跳到again,即程序再一次循环执行
again12:
sti
mov ah,3 ;赋数码管初值为30秒
mov buf,ah
mov ah,0
mov buf+1,ah
again2:
in al,dx
and al,3
or al,10000100b; 使南北红灯亮,东西绿灯亮
out dx,al
call displayy ;数码管显示
mov ah,buf ;判断数码管显示是否为零
mov al,buf+1
cmp ax,0
jne again2 ;不是零继续显示
in al,dx
and al,11111011b ;使东西绿灯灭
out dx,al
mov ah,0 ;赋数码管初值为5秒
mov buf,ah
mov ah,5
mov buf+1,ah
yellow1:
mov cx,30 ;设置循环次数
cx01:
cmp cx,0
jne cxNot01 ;cx不是0继续显示
in al,dx
xor al,00001000b ;改变黄灯状态
out dx,al
jmp Time01
cxNot01:
call displayy ;数码管显示
dec cx ;cx减1
call delayMs ;延时
jmp cx01
Time01:
mov ah,buf ;判断黄灯闪烁时间是否结束
mov al,buf+1
cmp ax,0
jne yellow1 ;时间不是0继续闪烁
mov ah,0bh
int 21h
test al,al
je AGAIN11 ;有键按下,则退出;否则跳到跳转中继处。
mov al,intimr
out 21h,al ;恢复原状态
mov dx,intoff
mov ax,intseg
mov ds,ax
mov ax,250bh
int 21h
sti
.exit ;返回
;////////////////////////////////////////////
delay proc ;延时
push cx
mov cx,3000
delay1:
loop delay1
pop cx
ret
delay endp
;//////////////newobh中断服务程序,实现数码管显示数字减一//////////
new0bh proc
sti
push ax
push ds
mov ax,@data
mov ds,ax
mov al,buf+1 ;读出个位数秒数
cmp al,0
je intp1 ;为0跳转到 intp1
dec al ;不为0,个位数字减一
mov buf+1,al ;写回buff中
jmp intp2 ;十位数字不改变并跳到结束
intp1:
mov ah,buf ;读出十位数字
cmp ah,0
je intp2 ;十位数字为0,直接结束
dec ah ;十位数字不为0,使其减一
mov buf,ah ; 写回buff中
mov al,9 ;使个位数字为9
mov buf+1,al ;写回
intp2:
mov al,20h ;发送EOI
out 20h,al
pop ds
pop ax
iret
new0bh endp
;///////////////led显示////////////////////
displayy proc
push ax
push bx
push cx
push dx
mov bl,buf ;bl为要显示的数
mov bh,0
mov al,led[bx] ;求出对应的led数码
mov dx,288h ;自8255A的口输出
out dx,al
mov dx,28ah
in al,dx
or al,2 ;使左边的数码管亮
out dx,al
call delay ;延时
;
mov dx,28ah ;关掉数码管显示
in al,dx
and al,11111101b
out dx,al
;
mov bl,buf+1 ;bl为要显示的数
mov bh,0
mov al,led[bx] ;求出对应的led数码
mov dx,288h ;自8255A的口输出
out dx,al
mov dx,28ah
in al,dx
or al,1 ;使右边的数码管亮
out dx,al
call delay ;延时
;
mov dx,28ah ;关掉数码管显示
in al,dx
and al,11111110b
out dx,al
pop dx
pop cx
pop bx
pop ax
ret
displayy endp
;////////////黄灯延时子程序////////////////
delayMs proc
push cx
push dx
push ax
push bx
mov cx,0
loop1: ;实现循环65536次
cmp cx,0
loop loop1
pop bx
pop ax
pop dx
pop cx
ret
delayMs endp
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -