在段0偏移46Ch(或者在seg 40h,offs 6Ch)有一个4字节的计数器,由PC BIOS维护和更新。它每秒增加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指令直接在十进制中增加数字而无需进行任何转换。
以下是如何完成所有操作的方法:
bits 16
org 0x100
mov ax, 0
mov cx, 256
NextNumber:
%if 1
push ax
mov dx, 0
div word [ten]
push dx
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数据区”。