You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

16位实模式裸机nasm汇编实现毫秒级休眠及打印延迟方案问询

16位实模式汇编延迟功能实现方案

在16位实模式的裸机环境下,可以直接调用BIOS提供的时钟中断实现指定时长的延迟,无需额外硬件驱动。

实现原理

  • 系统内置的定时器会以约18.2Hz的频率触发中断,对应每次中断间隔约55ms
  • BIOS维护了全局的时钟滴答计数器,每触发一次定时器中断,计数器值加1
  • 调用int 0x1A中断的AH=0x00子功能,可以读取当前的滴答计数器值,结果存储在CX:DX寄存器组中
  • 你需要的300ms延迟对应约6次滴答计数(55ms * 6 = 330ms,误差可忽略,完全满足字符打印的间隔效果要求)

修改后的完整打印代码

[bits 16]    ; 运行在16位模式下
[org 0x7c00] ; 设置程序起始地址

init: 
  mov si, msg  ; 将字符串msg的地址加载到SI寄存器
  mov ah, 0x0e ; 设置AH为0xe,对应BIOS中断的 teletype 打印功能
print_char:
  lodsb     ; 将SI指向的字节加载到AL,同时SI地址自增1
  cmp al, 0 ; 判断AL是否为字符串结束标记0
  je done   ; 到字符串末尾则跳转到结束逻辑
  int 0x10  ; 调用BIOS中断打印当前AL中的字符
  mov cx, 6 ; 设置需要等待的滴答数,6次对应约300ms
  call delay ; 调用延迟函数
  jmp print_char ; 循环处理下一个字符

; 延迟函数:输入CX为需要等待的滴答数
delay:
    push ax
    push cx
    push dx
.wait_loop:
    mov ah, 0x00
    int 0x1A          ; 读取当前滴答计数到CX:DX
    mov bx, dx        ; 保存当前低16位计数
.check_tick:
    mov ah, 0x00
    int 0x1A
    cmp dx, bx        ; 对比当前计数和之前保存的计数
    je .check_tick    ; 计数未更新就继续轮询
    dec cx            ; 完成一次滴答等待,计数减1
    jnz .wait_loop    ; 未到指定滴答数就继续循环
    pop dx
    pop cx
    pop ax
    ret

done:
  hlt ; 停止CPU执行

msg: db "The quick brown fox jumps over the lazy dog.", 0 ; 要打印的字符串,末尾补0作为结束标记

times 510-($-$$) db 0           ; 填充0直到程序总大小为510字节
dw 0xaa55                       ; 引导扇区魔数,BIOS识别该值才会认为这是可引导的程序

精度调整说明

如果需要更精准的延迟,可以直接对PIT(可编程间隔定时器)芯片进行编程,设置自定义的定时器频率,实现毫秒级的精准控制,实现复杂度更高,对于打字效果的场景不需要这么高的精度,上述方案已经满足需求。

内容的提问来源于stack exchange,提问作者H4ZE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 03:18:02