用汇编语言设计体育比赛计时程序,程序运行,屏幕显示00:00:00,并开始按秒计时。每按下一次空格键,在下一行显示当前暂停的时刻,最多可计10次暂停时间。按下Q键,程序结束。用dos对程序进行调试。
汇编
基于new bing的编写参考:
.model small
.stack 100h
.data
time db 0, 0, 0, '$' ; 存储时间的变量
pause_times db 10 ; 剩余可暂停次数
.code
start:
mov ax, @data ; 初始化数据段寄存器
mov ds, ax
mov ah, 0 ; 按键输入函数号
int 16h ; 等待用户按下键盘按键
cmp ah, 20h ; 如果按下的是空格键
je pause_time ; 跳转到暂停计时处理
cmp ah, 10h ; 如果按下的是Q键
je end_program ; 跳转到程序结束处理
jmp start ; 继续等待用户按键
pause_time:
cmp pause_times, 0 ; 如果剩余可暂停次数为0
je start ; 返回继续等待用户按键
dec pause_times ; 剩余可暂停次数减1
mov ah, 0 ; 获取当前时刻的函数号
int 1Ah ; 获取当前时刻,存储在CX:DX中
mov bx, offset time ; 将时间变量的地址存储在BX中
mov [bx], dl ; 将秒存储在time[0]
mov [bx+1], dh ; 将分存储在time[1]
mov [bx+2], ch ; 将时存储在time[2]
add bx, 3 ; 偏移3字节,指向字符串结束符
mov byte ptr [bx], '$' ; 在字符串结束处添加结束符
mov ah, 9 ; 显示字符串函数号
mov dx, offset time ; 将时间变量的地址存储在DX中
int 21h ; 显示时间字符串
jmp start ; 返回继续等待用户按键
end_program:
mov ah, 4Ch ; 程序结束函数号
mov al, 0 ; 返回值为0
int 21h
end start
这个程序使用BIOS中断来读取键盘输入和获取系统时间,并使用DOS中断来在屏幕上显示信息。在程序开始时,在屏幕左上角显示"00:00:00",然后等待用户按下空格键或Q键。如果按下空格键,程序会将此时的时间显示在屏幕下方,并将剩余可暂停次数减1;如果按下Q键,程序会直接结束。程序最多可以暂停10次。
请注意,由于不同的汇编语言实现有所不同,这份代码可能需要根据具体情况进行适当修改才能运行。
可以参考下
;交通灯源码
MY_STACK SEGMENT PARA 'STACK'
DB 100 DUP(?)
MY_STACK ENDS
MY_DATA SEGMENT PARA 'DATA'
IO_9054base_address DB 4 DUP(0) ;PCI 卡 9054 芯片 I/O 基地址暂存空间
IO_base_address DB 4 DUP(0) ;PCI 卡 I/O 基地址暂存空间
pcicardnotfind DB 0DH,0AH,'pci card not find or address/interrupt error !!!',0DH,0AH,'$'
GOOD DB 0DH,0AH,'The Program is Executing !',0DH,0AH,'$'
P8255_A DW 0000H
P8255_B DW 0001H
P8255_C DW 0002H
P8255_MODE DW 0003H DELAY_SET EQU 5fffH DELAY_SET1 EQU 18ffH
MES2 DB ' PCI CONFIG READ ERROR! $' MY_DATA ENDs
MY_CODE SEGMENT PARA 'CODE'
MY_PROC PROC FAR
ASSUME CS:MY_CODE, DS:MY_DATA, SS:MY_STACK
START:
.386 ;386 模式编译
MOV AX,MY_DATA
MOV DS,AX
MOV ES,AX
MOV AX,MY_STACK
MOV SS,AX
CALL FINDPCI ;自动查找 PCI 卡资源及 IO 口基址
; MOV
MOV CX,word ptr IO_base_address
CX,0E800H ;直接加入(E800:本机 PCI 卡 IO 口基址)
ADD P8255_A,CX ;PCI 卡 IO 基址+偏移
ADD P8255_B,CX
ADD P8255_C,CX
ADD P8255_MODE,CX
MOV MOV DX,P8255_MODE
AL,80H ;3 个口全部为输出
OUT DX,AL
MOV DX,P8255_A
CALL ST0 ;全为红灯
TRAFFIC1: CALL
CALL ST1
ST5 ;南北为绿灯,东西为红灯
CALL ST2 ;南北红灯闪烁,东西为红灯
CALL ST3
CALL ST6 ;南北为红灯,东西为绿灯
CALL ST4 ;南北为红灯,东西黄灯闪烁
CALL BREAK
JMP TRAFFIC1
MY_PROC ENDp
ST0 PROC NEAR
MOV AL,1BH
OUT DX,AL
CALL DELAY
RET
ST0 ENDp
ST1 PROC NEAR
MOV DX,P8255_A
MOV AL,0EDH
OUT DX,AL
CALL DELAY
CALL DELAY
CALL DELAY
RET
ST1 ENDp
ST5 PROC NEAR
MOV DX,P8255_A
MOV AL,0EBH
OUT DX,AL
CALL DELAY
RET
ST5 ENDp
ST2 PROC NEAR
MOV CX,5H
ST20: MOV AL,0EBH
OUT DX,AL
CALL DELAY1
MOV AL,0EFH
OUT DX,Al
CALL DELAY1
LOOP ST20
RET
ST2 ENDp
ST3 PROC NEAR
MOV AL,0DEH
OUT DX,AL
CALL DELAY
CALL DELAY
CALL DELAY
RET
ST3 ENDp
ST6 PROC NEAR
MOV DX,P8255_A
MOV AL,0BEH
OUT DX,AL
CALL DELAY
RET
ST6 ENDp
ST4 PROC NEAR
MOV CX,5H
ST40: MOV AL,0BEH
OUT DX,AL
CALL DELAY1
MOV AL,0FEH
OUT DX,AL
CALL DELAY1
LOOP ST40
RET
ST4 ENDp
;
;*****************************************************************************
; /* 延时子程序 */
;*****************************************************************************
;
DELAY PROC NEAR ;延时程序
PUSHF PUSH DX
PUSH CX
MOV DX,DELAY_SET
D1: MOV CX,-1
D2: DEC CX
JNZ D2
DEC DX
JNZ D1
POP CX
POP DX POPF
RET
DELAY ENDp
DELAY1 PROC NEAR ;延时程序
PUSHF PUSH DX
PUSH CX
MOV DX,DELAY_SET1
D3: MOV CX,-1
D4: DEC CX
JNZ D4
DEC DX
JNZ D3
POP CX
POP DX POPF
RET
DELAY1 ENDp
;
;*****************************************************************************
; /* 按任意键退出子程序 */
;*****************************************************************************
;
BREAK PROC NEAR ;按任意键退出
PUSHF PUSH AX
PUSH DX
MOV AH,06H
MOV DL,0FFH
INT 21H
JE RETURN
MOV AX,4C00H
INT 21H
RETURN: POP DX
POP AX POPF
RET
BREAK ENDP
;
;*****************************************************************************
; /* 找卡子程序 */
;*****************************************************************************
;
;FUNCTION CODE
IO_port_addre EQU 0CF8H ;32 位配置地址端口
IO_port_data EQU 0CFCH ;32 位配置数据端口
IO_PLX_ID EQU 200810B5H ;PCI 卡设备及厂商 ID
BADR0 = 10H ;基地址寄存器 0
BADR1 = 14H ;基地址寄存器 1
BADR2 = 18H ;基地址寄存器 2
BADR3 = 1CH ;基地址寄存器 3
FINDPCI PROC NEAR ;查找 PCI 卡资源并显示
PUSHAD PUSHFD
MOV EBX,080000000H
FINDPCI_next:
ADD EBX,100H
CMP EBX,081000000H
JNZ findpci_continue
MOV DX,offset pcicardnotfind ;显示未找到 PCI 卡提示信息
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H ;退出
findpci_continue:
MOV
MOV DX,IO_port_addre
EAX,EBX
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
CMP EAX,IO_PLX_ID
JNZ findpci_next ;检查是否发现 PCI 卡
MOV DX,IO_port_addre
MOV EAX,EBX
ADD
OUT EAX,BADR1
DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV dword ptr IO_9054base_address,EAX
AND EAX,1
JZ findPCI_next ;检查是否为 i/o 基址信息
MOV EAX,dword ptr IO_9054base_address
AND EAX,0fffffffeh
MOV dword ptr IO_9054base_address,EAX ;去除 i/o 指示位并保存
MOV DX,IO_port_addre
MOV EAX,EBX
ADD EAX,BADR2
OUT DX,EAX ;写地址口
MOV
IN DX,IO_port_data
EAX,DX ;读数据口
MOV dword ptr IO_base_address,EAX
AND
JZ EAX,1
findPCI_next ;检查是否为 i/o 基址信息
MOV EAX,dword ptr IO_base_address
AND
MOV EAX,0fffffffeh
dword ptr IO_base_address,EAX ;去除 i/o 指示位并保存
MOV DX,offset good ;显示开始执行程序信息
MOV AH,09H
INT 21H
POPfd
POPad
RET
findPCI ENDP
MY_CODE ENDS
END START
;I/O 实验源码
DATA SEGMENT DELAY_SET EQU 0FFFH L_TO_R DB ?
R_TO_L DB ?
DATA ENDs
CODE SEGMENT
ASSUME DS : DATA, CS : CODE START:
MOV AX, DATA
MOV DS, AX
MOV L_TO_R, 07FH MOV R_TO_L, 0FEH MOV DX, 0ec03h MOV AL, 89h
OUT DX, AL
X:
MOV DX, 0ec02h IN AL, DX CMP AL, 0h
JE FLOW_1 CMP AL, 00fh JE FLOW_2
MOV DX, 0ec00h OUT DX, AL CALL DELAY JMP START
FLOW_1:
MOV AL, L_TO_R MOV AH, R_TO_L ROR AL, 1
MOV L_TO_R, AL ROL AH, 1
MOV R_TO_L, AH JMP SHOW_1
FLOW_2:
MOV AL, R_TO_L MOV AH, L_TO_R ROR AL, 1
MOV L_TO_R, AL ROL AH, 1
MOV R_TO_L, AH JMP SHOW_2
SHOW_1:
MOV DX, 0ec00h OUT DX, AL MOV AL, AH MOV DX, 0ec01h OUT DX, AL CALL DELAY JMP X
SHOW_2:
MOV DX, 0ec01h OUT DX, AL MOV AL, AH MOV DX, 0ec00h OUT DX, AL CALL DELAY JMP X
DELAY PROC NEAR
PUSHF
PUSH DX
PUSH CX
MOV DX,DELAY_SET
D1: MOV CX,-1
D2: DEC CX
JNZ D2
DEC DX
JNZ D1
POP CX
POP DX
POPF
RET
DELAY ENDp
CODE ENDs END START
;流水灯源码
MY_STACK SEGMENT PARA 'STACK'
DB 100 DUP(?)
MY_STACK ENDS
MY_DATA SEGMENT PARA 'DATA'
IO_9054base_address DB 4 DUP(0) ;PCI 卡 9054 芯片 I/O 基地址暂存空间
IO_base_address DB 4 DUP(0) ;PCI 卡 I/O 基地址暂存空间
pcicardnotfind DB 0DH,0AH,'pci card not find or address/interrupt error !!!',0DH,0AH,'$'
GOOD DB 0DH,0AH,'The Program is Executing !',0DH,0AH,'$'
LA DB ?
LB DB ?
P8255_A DW 0000H
P8255_B DW 0001H
P8255_C DW 0002H
P8255_MODE DW 0003H DELAY_SET EQU 11FFH
MES2 DB ' PCI CONFIG READ ERROR! $' MY_DATA ENDs
MY_CODE SEGMENT PARA 'CODE' MY_PROC PROC FAR
ASSUME CS:MY_CODE, DS:MY_DATA, SS:MY_STACK
START:
.386 ;386 模式编译
MOV AX,MY_DATA
MOV DS,AX
MOV ES,AX
MOV AX,MY_STACK
MOV SS,AX
CALL FINDPCI ;自动查找 PCI 卡资源及 IO 口基址
MOV
ADD CX,word ptr IO_base_address
P8255_A,CX ;PCI 卡 IO 基址+偏移
ADD P8255_B,CX
ADD P8255_C,CX
ADD P8255_MODE,CX
MOV DX,P8255_MODE ;8255 初始化,三个口全为输出
MOV AL,80H
OUT DX,AL
MOV DX,P8255_A ;PA 口赋初值
MOV AL,7FH
OUT DX,AL
MOV LA,AL
MOV DX,P8255_B ;PB 口赋初值
MOV AL,0FEH
OUT DX,AL
MOV LB,AL
CALL DELAY
A1: MOV AL,LA ;PA 口数据右移一位
ROL AL,1
MOV LA,AL
MOV DX,P8255_A
OUT DX,AL
MOV AL,LB
ROR AL,1
MOV LB,AL
MOV DX,P8255_B ;PB 口数据右移一位
OUT DX,AL
CALL DELAY ;延时
CALL BREAK ;按任意键退出
JMP A1
MY_PROC ENDp
DELAY PROC NEAR ;延时程序
PUSHF
PUSH DX
D1: PUSH MOV MOV CX DX,DELAY_SET CX,-1
D2:
DELAY DEC
JNZ DEC JNZ POP POP POPF RET ENDp CX
D2 DX D1 CX DX
BREAK
RETURN: PROC MOV MOV INT JE MOV INT RET NEAR AH,06H DL,0FFH 21H RETURN AX,4C00H 21H
BREAK ENDP
;*****************************************************************************
; /* 找卡子程序 */
;*****************************************************************************
IO_port_addre EQU 0CF8H ;32 位配置地址端口
IO_port_data EQU 0CFCH ;32 位配置数据端口
IO_PLX_ID EQU 200810B5H ;PCI 卡设备及厂商 ID
BADR0 = 10H ;基地址寄存器 0
BADR1 = 14H ;基地址寄存器 1
BADR2 = 18H ;基地址寄存器 2
BADR3 = 1CH ;基地址寄存器 3
FINDPCI PROC NEAR ;查找 PCI 卡资源并显示
PUSHAD PUSHFD
MOV EBX,080000000H
FINDPCI_next:
ADD EBX,100H
CMP EBX,081000000H
JNZ findpci_continue
MOV DX,offset pcicardnotfind ;显示未找到 PCI 卡提示信息
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H ;退出
findpci_continue:
MOV
MOV DX,IO_port_addre
EAX,EBX
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
CMP
JNZ EAX,IO_PLX_ID
findpci_next ;检查是否发现 PCI 卡
MOV DX,IO_port_addre
MOV EAX,EBX
ADD EAX,BADR1
OUT DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV dword ptr IO_9054base_address,EAX
AND EAX,1
JZ findPCI_next ;检查是否为 i/o 基址信息
MOV EAX,dword ptr IO_9054base_address
AND EAX,0fffffffeh
MOV dword ptr IO_9054base_address,EAX ;去除 i/o 指示位并保存
MOV DX,IO_port_addre
MOV EAX,EBX
ADD
OUT EAX,BADR2
DX,EAX ;写地址口
MOV DX,IO_port_data
IN EAX,DX ;读数据口
MOV AND dword ptr IO_base_address,EAX EAX,1
JZ findPCI_next ;检查是否为 i/o 基址信息
MOV EAX,dword ptr IO_base_address
AND EAX,0fffffffeh
MOV dword ptr IO_base_address,EAX ;去除 i/o 指示位并保存
MOV DX,offset good ;显示开始执行程序信息
MOV AH,09H
INT 21H
POPfd POPad RET
findPCI ENDP
MY_CODE ENDS END START
汇编示例
.model small
.stack 100h
.data
hour db 2,":$"
minute db 2,":$"
second db 2,"$"
buffer db 10 DUP("$")
count db 0
.code
main proc
mov ax, @data
mov ds, ax
; 初始化屏幕
mov ah, 0
mov al, 3
int 10h
; 显示时分秒
mov ah, 2
mov dl, hour
int 21h
mov dl, minute
int 21h
mov dl, second
int 21h
; 开始计时
mov ah, 0
int 16h
start:
; 更新秒
mov ah, 2
inc second
cmp second, 60
jne time_ok
mov second, 0
inc minute
cmp minute, 60
jne time_ok
mov minute, 0
inc hour
cmp hour, 24
jne time_ok
mov hour, 0
jmp time_ok
time_ok:
mov dl, hour
int 21h
mov dl, minute
int 21h
mov dl, second
int 21h
; 监听空格键或Q键
mov ah, 0
int 16h
cmp ah, 20h
je pause
cmp ah, 10h
je exit
; 继续计时
jmp start
pause:
; 显示暂停时刻
cmp count, 10
jae start
mov ah, 2
mov dl, '0' ; 十位
int 21h
mov dl, hour
and dl, 0fh
add dl, '0'
int 21h
mov dl, ':'
int 21h
mov dl, '0' ; 分钟十位
int 21h
mov dl, minute
and dl, 0fh
add dl, '0'
int 21h
mov dl, ':'
int 21h
mov dl, '0' ; 秒十位
int 21h
mov dl, second
and dl, 0fh
add dl, '0'
int 21h
inc count
; 继续监听键盘
jmp start
exit:
; 显示暂停时刻
mov ah, 2
mov dl, 13
int 21h
mov dl, 10
int 21h
mov dl, "Paused Times:"
int 21h
mov cx, count
mov si, OFFSET buffer
mov ah, 2
mov dl, 13
int 21h
mov dl, 10
int 21h
loop1:
cmp cx, 0
je end_loop1
mov ah, 2
mov dl, " "
int 21h
mov dl, si[0]
int 21h
mov dl, ':'
int 21h
mov dl, si[2]
int 21h
mov dl, ':'
int 21h
mov dl, si[4]
int 21h
add si, 6
dec cx
jmp loop1
end_loop1:
; 结束程序
mov ah, 4ch
mov al, 0
int 21h
main endp
end main
汇编语言我不太熟,我给你找些资料,看下是否满足你的需求:
汇编课程设计报告计时器:https://www.docin.com/p-2701912997.html
用汇编语言编写一个时钟程序,在微机屏幕上显示当前时间的时、分、秒:https://zhidao.baidu.com/question/101839913.html
汇编语言:时钟实验:https://blog.csdn.net/m0_49448277/article/details/116291515
以上是我给你找的资料,你注意下最后一个博文,也是基于DOS的,应该与你的需求比较接近。
section .data
time db 0 ; 计时器初始值为0
pauseTimes db 0 ; 暂停时间计数器初始值为0
pauseTable db 10 dup(0) ; 存储暂停时间的表格,最多10次暂停
section .text
global _start
_start:
mov ax, 0x0003 ; 将视频模式设置为文本模式
int 0x10
mov ah, 0x02 ; 设置光标位置
mov bh, 0x00 ; 页号为0
mov dh, 0x00 ; 行号为0
mov dl, 0x00 ; 列号为0
int 0x10
mov ah, 0x01 ; 读取键盘输入
int 0x16
cmp al, 0x51 ; 如果按下的是 'Q' 键,则退出程序
je _exit
cmp al, 0x20 ; 如果按下的是空格键,则记录暂停时间
jne _start
cmp byte [pauseTimes], 10 ; 判断是否达到最大暂停次数
jae _start
mov ah, 0x02 ; 获取当前时间
int 0x1A
mov byte [pauseTable + bx], ch ; 存储小时数
mov byte [pauseTable + bx + 1], cl ; 存储分钟数
mov byte [pauseTable + bx + 2], dh ; 存储秒数
inc byte [pauseTimes] ; 暂停时间计数器加一
jmp _start
_exit:
mov ah, 0x4C ; 退出程序
xor al, al ; 返回值为0
int 0x21