Имеется 4-байтовый счетчик со смещением сегмента 0 46Ch (или, альтернативно, на seg 40h, с 6Ch), который поддерживается и обновляется BIOS 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 function 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
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, в которых описано, как работает каждая инструкция.Читать их.Также загрузите Ralf Brown's Interrupt List
, в котором описаны все функции BIOS и DOS.Вы должны знать некоторые из них, чтобы сделать ввод / вывод.Также есть HelpPC
и TechHelp
, которые удобно описывают многие вещи BIOS и DOS, например BIOS Data Area
, где живет вышеупомянутый счетчик.