加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

如何在屏幕上显示一个数字,并使用DOS x86程序集睡眠一秒钟?

发布时间:2020-12-13 20:29:24 所属栏目:Windows 来源:网络整理
导读:我正在使用NASM 16 BITS.我正在尝试做一个简单的汇编代码,打印0到255之间的数字,每个数字之间间隔1秒.这是我到目前为止: [bits 16]mov ax,csmov ds,axmov cx,255mov ax,0myloop: ;print in screen ax value ;wait 1 second inc axloop myloop 我不知道如何
我正在使用NASM 16 BITS.我正在尝试做一个简单的汇编代码,打印0到255之间的数字,每个数字之间间隔1秒.这是我到目前为止:
[bits 16]

mov ax,cs
mov ds,ax
mov cx,255
mov ax,0

myloop:
    ;print in screen ax value
    ;wait 1 second
    inc ax

loop myloop

我不知道如何在屏幕上打印ax的值,以及如何等待1秒(将它们放在代码中的注释中).

在PC BIOS维护和更新的段0偏移46Ch(或者在段40h,关闭6Ch)有一个4字节计数器.它每秒增加18.2次.计算此计数器最低字节或字的18个变化可能是等待大约一秒钟的最简单方法:
mov  ax,0
mov  ds,ax
mov  cx,18
mov  bx,[46Ch]
WaitForAnotherChange:
NoChange:
mov  ax,[46Ch]
cmp  ax,bx
je   NoChange
mov  bx,ax
loop WaitForAnotherChange

要打印十进制数,您需要将二进制数转换为十进制数,获取单个数字并打印它们.您将数字除以10并收集余数.例如.:

123:
123/10:商12,余数3
12/10:商1,余数2
1/10:商0,余数1

通过重复除以10,您可以按相反的顺序得到余数中的各个数字:3,2,1.然后用DOS int 21h函数2打印它们(将2加载到AH中,将字符的ASCII码加载到DL中,执行int 21h).

另一种非常适合您的问题的变体是使用DAA指令直接以十进制递增数字而不进行任何转换.

以下是这一切的完成方式:

; file: counter.asm
; assemble: nasm.exe counter.asm -f bin -o counter.com

bits 16
org 0x100

    mov  ax,0 ; initial number
    mov  cx,256 ; how many numbers

NextNumber:
%if 1 ; change to 0 to use the DAA-based method
    push ax

    mov  dx,0
    div  word [ten]
    push dx

    mov  dx,0
    div  word [ten]
    push dx

    pop  dx
    call PrintDigit
    pop  dx
    call PrintDigit
    pop  dx
    call PrintDigit

    pop  ax

    call PrintNewLine
    call Wait1s

    inc  ax
%else
    mov  dl,ah
    call PrintDigit

    mov  dl,al
    shr  dl,4
    call PrintDigit

    mov  dl,al
    and  dl,0Fh
    call PrintDigit

    call PrintNewLine
    call Wait1s

    add  al,1
    daa
    adc  ah,0
%endif

    loop NextNumber
    ret

PrintDigit:
    pusha
    mov   ah,2
    add   dl,'0'
    int   21h
    popa
    ret

PrintNewLine:
    pusha
    mov   dx,CRLF
    mov   ah,9
    int   21h
    popa
    ret

Wait1s:
    pusha
    push ds

    mov  ax,0
    mov  ds,ax

    mov  cx,18
    mov  bx,[46Ch]
WaitForAnotherChange:
NoChange:
    mov  ax,[46Ch]
    cmp  ax,bx
    je   NoChange
    mov  bx,ax
    loop WaitForAnotherChange

    pop  ds
    popa
    ret

ten dw 10
CRLF db 13,10,"$"

如果您不喜欢前导零或最后1秒延迟,则可以有条件地跳过它们.

下载描述每条指令如何工作的Intel和/或AMD x86 CPU手册.读它们.另外,下载Ralf Brown的中断列表,它描述了每个BIOS和DOS功能.你需要知道其中一些做I / O.还有HelpPC和TechHelp可以方便地描述许多BIOS和DOS之类的东西,比如上述计数器所在的BIOS数据区.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读