小亦003 发表于 2023-12-3 14:53:38

汇编:如何设计一个电子时钟?

已知int 21h是DOS中断,当AH=2CH,获取系统的时间,CH=小时CL=分钟DH=秒,DL=百分秒。
例如:
MOVAH,2CH
INT 21H
则指令执行后,则当前时间存放在CH=小时CL=分钟DH=秒,DL=百分秒。
请设计一个电子时钟,实现在终端显示当前时间,显示格式为:HH:MM:SS:us。例如:显示08:01:00:000,然后数字不断变化。


思路:不断的循环中读取系统时间,将时间的CH,CL,DH,DL寄存器在指定显存中按指定格式显示。

yuanyuxixue 发表于 2023-12-3 14:53:39

基于X86的代码
.model small
.stack 100h

.data
disp_str db "Current time: HH:MM:SS:us$"
time_str db "                                           $"
hour db ?
min db ?
sec db ?
msec db ?
colon db ':'
zero db '0'

.code
main:
mov ax, @data
mov ds, ax
mov ah, 0Ch ; 调用int 21h中断,功能码AH=0Ch,设置文本和背景颜色
mov al, 0Eh ; 黑底白字
int 10h ; 调用int 10h中断,设置屏幕颜色

lea si, disp_str ; 打印显示信息字符串
mov ah, 09h
mov dx, si
int 21h

loop:
mov ah, 2Ch ; 获取当前时间
int 21h
mov hour, ch ; 将当前的小时数保存到变量hour中
mov min, cl ; 将当前的分钟数保存到变量min中
mov sec, dh ; 将当前的秒数保存到变量sec中
mov msec, dl ; 将当前的百分秒数保存到变量msec中

; 将各个时间变量转换为字符串
call convert_hour
call convert_min
call convert_sec
call convert_msec

; 将时间字符串写入指定显存区域
lea si, time_str
mov di, 0B800h ; 显存地址
mov cx, 16 ; 时间字符串长度
rep movsb ; 将字符串写入显存

; 休眠一段时间
mov cx, 12500d ; 大约100ms
call delay

; 跳转回循环开始,继续更新时间
jmp loop

; 在左侧添加0以保持两位数的格式
add_zero:
cmp al, 10 ; 判断是否小于10
jge skip ; 若大于等于10则转到skip
mov ah, 0 ; 使得ah寄存器置0
mov al, zero ; 让al寄存器变成'0'
lea si, time_str ; 增加si的值,使得指向下一个字符
mov , al ; 将'0'写入显存中
skip:
ret ; 返回子程序

convert_hour:
mov al, hour ; 取出小时数
div byte ptr 10 ; 将小时数除以10
add al, '0' ; 将商转换为数字字符
mov , al ; 将数字字符写入字符串中
call add_zero ; 将个位数左侧补零
add byte ptr , colon ; 添加冒号
ret

convert_min:
mov al, min ; 取出分钟数
div byte ptr 10 ; 将分钟数除以10
add al, '0' ; 将商转换为数字字符
mov , al ; 将数字字符写入字符串中
call add_zero ; 将个位数左侧补零
add byte ptr , colon ; 添加冒号
ret

convert_sec:
mov al, sec ; 取出秒数
div byte ptr 10 ; 将秒数除以10
add al, '0' ; 将商转换为数字字符
mov , al ; 将数字字符写入字符串中
call add_zero ; 将个位数左侧补零
add byte ptr , colon ; 添加冒号
ret

convert_msec:
mov al, msec ; 取出百分秒数
push ax ; AX寄存器中保存百分秒数
mov al, 10d ; 除数是10
xor ah, ah ; ah寄存器清零
div al ; 将百分秒数除以10
pop ax ; 恢复百分秒数

FishC_GPT 发表于 2023-12-3 14:54:07

要设计一个电子时钟,你可以按照以下步骤进行操作:

1. 首先,需要定义一些常量和变量来存储时间和显存地址。例如,你可以定义一个变量 currentTime 来存储当前时间,用一个变量来存储显存的地址,比如 screenMemory。

2. 在主程序中,使用一个无限循环来不断获取系统时间并显示在终端上。你可以使用 int 21h 中断来获取系统时间,并将小时、分钟、秒和百分秒存储在适当的寄存器中。

3. 使用 MOV 指令将从 int 21h 获取到的时间值保存到你定义的 currentTime 变量中。

4. 接下来,你需要将 currentTime 的每个部分(小时、分钟、秒和百分秒)格式化为两位数。你可以使用除法和取模运算符来计算每个部分的十位数和个位数,并将它们转换为 ASCII 码字符。

5. 将格式化后的时间值显示在终端上,你可以使用 INT 10H 中断来执行屏幕输出操作。将时间值的 ASCII 字符写入到显存中相应的位置上。

6. 最后,使用一个延时函数来控制时间的变化速度,以便能够让时间在终端上连续地更新。你可以使用循环和计数来实现简单的延时函数。

以下是一个汇编语言的示例代码,实现了上述的电子时钟功能:

.model small
.stack 100h

.data
currentTime db 0, 0, 0, 0; 存储当前时间,依次为小时、分钟、秒和百分秒
screenMemory dw 0B800h   ; 显存地址

.code
main proc
    mov ax, @data
    mov ds, ax

    mov ah, 2Ch      ; 获取系统时间
    int 21h

    mov currentTime, ch; 保存小时
    mov currentTime+1, cl; 保存分钟
    mov currentTime+2, dh; 保存秒
    mov currentTime+3, dl; 保存百分秒

    mov si, offset currentTime; 将si指向存储当前时间的变量

loop_start:
    ; 格式化当前时间的小时部分
    mov al,
    xor ah, ah
    mov bl, 10
    div bl
    add ax, 3030h
    mov , ax

    ; 格式化当前时间的分钟部分
    mov al,
    xor ah, ah
    div bl
    add ax, 3030h
    mov , ax

    ; 格式化当前时间的秒部分
    mov al,
    xor ah, ah
    div bl
    add ax, 3030h
    mov , ax

    ; 格式化当前时间的百分秒部分
    mov al,
    xor ah, ah
    xor bh, bh
    mov bl, 100
    div bl
    add ax, 3030h
    mov , ax

    jmp loop_start; 无限循环显示时间

main endp
end main

请注意,这只是一个简单的示例代码,你可能需要根据具体的汇编器和操作系统进行适当的调整。此外,该代码只是在终端上不断显示时间,如果你想要更复杂的功能,比如增加闹钟或者实现闪烁效果,你可能需要做更多的工作。希望对你有所帮助!

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。

简单滴滴 发表于 2023-12-4 19:24:05

FishC_GPT 发表于 2023-12-3 14:54
要设计一个电子时钟,你可以按照以下步骤进行操作:

1. 首先,需要定义一些常量和变量来存储时间和显存地 ...

厉害

FishC_GPT 发表于 2023-12-4 19:24:15

简单滴滴 发表于 2023-12-04 19:24
厉害

谢谢夸奖!如果有任何其他问题,我都会尽力帮助你。编程是一门有趣而充满挑战的艺术,希望你在学习编程的路上不断进步,享受到编程带来的乐趣!

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。

wp231957 发表于 2023-12-10 10:12:07

FishC_GPT 发表于 2023-12-4 19:24
谢谢夸奖!如果有任何其他问题,我都会尽力帮助你。编程是一门有趣而充满挑战的艺术,希望你在学习编程的 ...

int 21这个指令在windows下 无法使用

人造人 发表于 2023-12-10 10:37:44

wp231957 发表于 2023-12-10 10:12
int 21这个指令在windows下 无法使用

用虚拟机

wp231957 发表于 2023-12-10 10:39:54

人造人 发表于 2023-12-10 10:37
用虚拟机

虚拟一个MS-DOS系统   ??、感觉没啥意义

人造人 发表于 2023-12-10 11:01:45

wp231957 发表于 2023-12-10 10:39
虚拟一个MS-DOS系统   ??、感觉没啥意义

对,在虚拟机中安装MS-DOS
当然有意义,为了学习16位实模式

小甲鱼的二师兄 发表于 2023-12-11 07:00:55

wp231957 发表于 2023-12-10 10:39
虚拟一个MS-DOS系统   ??、感觉没啥意义

16位汇编对于现代计算机确实意义不大丫~

linyuhui 发表于 2023-12-23 15:42:13

yuanyuxixue 发表于 2023-12-23 13:47
基于X86的代码
.model small
.stack 100h


有基于8086的吗

不二如是 发表于 2023-12-23 18:09:28

要设计一个显示当前时间的电子时钟,可以使用DOS中断(int 21h)来获取系统时间。

通过设置AH寄存器为2Ch,您可以通过CH、CL、DH、DL寄存器分别获取小时、分钟、秒和百分秒的值。

需要编写一个循环,不断地读取系统时间,并将其格式化为HH:MM:SS:us的形式显示在终端上。

程序不断更新,以显示当前的时间,例如“08:01:00:000”,并随着时间的推移持续变化。

在循环中实施适当的格式化和显示逻辑,以实现想要的显示格式。
页: [1]
查看完整版本: 汇编:如何设计一个电子时钟?