首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >汇编系统时间DOS

汇编系统时间DOS
EN

Stack Overflow用户
提问于 2014-06-22 04:12:48
回答 1查看 544关注 0票数 0

我写了一些代码:

代码语言:javascript
复制
petla:
mov ah,2
int 1ah

mov[sekunda], dh
mov ah, [sekunda]
mov cl, 4
and ah, 11110000b 
shr ah, cl  
mov dl, ah
add dl, '0'
mov ah, 2
int 21h

mov ah, [sekunda]
and ah, 00001111b   
mov dl, ah
add dl, '0'
mov ah, 2
int 21h

jmp petla

sekunda db 0

当我运行这个程序时,它显示了很多值(秒),如下所示:

代码语言:javascript
复制
12
12
12
12
12
13
13

如何修改代码,使其只显示一次值(一秒一个值)?

如何将代码修改为每5秒显示一次时间?

我需要在我的主代码中使用它,在x秒之后,一些东西将会改变。

EN

回答 1

Stack Overflow用户

发布于 2014-06-22 06:02:09

记住,对于一台计算机来说,秒()是非常长的一段时间(好吧,至少在过去的40-50年里是这样的!)

您的小程序正在非常快速地获取时间值,因此它可以获得几千(甚至百万)的当前时间。乘以一秒。

如果你只想要一个变化的输出,可以尝试下面这样的方法:(我们添加了一个比较)

代码语言:javascript
复制
petla:
    mov ah,2
    int 1ah             ; get time

    mov ah, [sekunda]   ; retrieve last good value
    cmp ah, dh          ; is it same as last good value?
    jz  pet1a           ; yup, ignore it, loop again!

    mov [sekunda], dh   ; save seconds

    mov ah, [sekunda]   ; get seconds value
    mov cl, 4           ; ready to shift 4 bits
    and ah, 11110000b   ; isolate top nybble
    shr ah, cl          ; shift into low nybble
    mov dl, ah          ; move into proper register for output
    add dl, '0'         ; magically transform into ASCII digit
    mov ah, 2           ; Select 'write char'
    int 21h             ; uh... write char!

    mov ah, [sekunda]   ; hey, this seems familiar!
    and ah, 00001111b   ; isolate lower nybble!
    mov dl, ah          ; no, really.. deja vu!
    add dl, '0'         ; TaaDaa, it's a char!
    mov ah, 2           ; Select 'write char'
    int 21h             ; make it so!

    jmp petla           ; do it again!  (make this a 'ret', see below)

现在这个小程序每秒都会不断地输出一个新的值。也许不是很有价值。

但是等等!还有更多!

如果您将最后一条指令(jmp pet1a)更改为一个return (ret),我们可以将其用作'wait_for_five_seconds‘例程的一部分...如下所示:

代码语言:javascript
复制
wait_for_five_seconds:
    mov al,5              ; how many seconds to wait
wait_for_al_seconds:      ; explained below
wait_loop:
    push ax               ; save our counter (al)
    call pet1a            ; this will call pet1a, which will not return until it has displayed a new second value
    pop ax                ; retrieve our counter (pet1a changes value of ah/al/ax, remember?)
    dec al                ; decrease al by one (does not set flags!!)
    or al,al              ; set flags
    jnz wait_loop         ; al=0?  nope, around we go again!
    ret                   ; go back to whomever called us!

现在,如果您想暂停5秒钟,您只需调用wait_for_five_seconds就可以了!

如果删除pet1a中写出字符的部分...然后,您将有一秒钟的静默延迟。对暂停很有用。

如果你想暂停17秒怎么办?嗯,我们的延迟是基于当我们进入wait_loop部分时al的值...那么,如果我们预加载al,然后调用等待位,结果会怎样呢?

代码语言:javascript
复制
    mov al, 17                 ; delay for 17 seconds!
    call wait_for_al_seconds   ; delay for whatever number is in al

但是要小心,如果al的值为0...它必须一直循环下去...0,-1,-2,... -127,-128,127,126...2,1,0 ...你会暂停256秒!(4分16秒!)。(请参阅Signed Number Representations了解为什么它在-128左右变得奇怪)

我希望这对你有所帮助,或许能给你一些启发。这不是一个理想的“暂停”解决方案,因为它不是精确的延迟,如果你在新的一秒之前调用pet1a ,那么第一次点击的延迟将非常小,然后其他点击的延迟将是整整几秒……因此,所需的5秒延迟可能是4.000001秒到5秒之间的任何时间。但这只是个开始。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24345481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档