Am Segment 0-Offset 46Ch (oder alternativ an Segment 40h, Offs 6Ch) wird ein 4-Byte-Zähler vom PC-BIOS verwaltet und aktualisiert. Es ist 18,2 mal pro Sekunde erhöht. 18 Änderungen im untersten Byte oder Wort dieses Zählers zu zählen ist wahrscheinlich der einfachste Weg, etwa des Wartens aus einem zweiten:
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
Dezimalzahlen drucken Sie Binärzahlen in dezimal konvertieren müssen, einzelne Ziffern erhalten und ausdrucken . Sie teilen die Zahl durch 10 und sammeln Reste. Beispiel:
123:
123/10: Quotient 12, Rest 3
12/10: Quotient 1, Rest 2
1/10: Quotient 0, Rest 1
Durch Teile wiederholt von 10 Sie erhalten die einzelnen Ziffern in den Resten in umgekehrter Reihenfolge: 3,2,1. Dann drucken Sie sie mit DOS int 21h Funktion 2 (laden Sie 2 in AH
, laden Sie den ASCII-Code des Zeichens in DL
, führen Sie int 21h
aus).
Eine alternative Variante, die für Ihr Problem sehr geeignet ist, wäre die Verwendung der Anweisung DAA
, um die Zahl direkt im Dezimalwert ohne Konvertierung zu erhöhen.
Hier ist, wie es getan werden kann:
; 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,"$"
Wenn Sie die führenden Nullen nicht mögen oder die letzten 1-Sekunden-Verzögerung, können Sie sie bedingt überspringen.
Laden Sie Intel und/oder AMD x86 CPU Handbücher herunter, die beschreiben, wie jede Anweisung funktioniert. Lese sie. Laden Sie auch die Ralf Brown's Interrupt List
herunter, die jede BIOS- und DOS-Funktion beschreibt. Sie müssen einige von ihnen kennen, um I/O zu tun. Es gibt auch HelpPC
und TechHelp
, die bequem viele BIOS- und DOS-Dinge wie die beschreiben, wo der oben genannte Zähler lebt.
Machst du das auf einem PC? –
@PavanManjunath Ja, ich mache es auf einem PC. Windows 7, 32 Bit. –
Für den Verzögerungsteil kannst du den letzten Beitrag im [this] (http://www.physicsforums.com/showthread.php?t=150424) Thread ansehen. Der Takt wird als 100 MHz angenommen. Aber Sie müssen den genauen Wert auf Ihrem Computer durch Versuch und Irrtum herausfinden. [This] (http://www.programsheaven.com/mb/x86_asm/272272/272273/re-sleep-function-/?S=B10000) Link sollte Ihnen auch helfen, die Verzögerung richtig zu bekommen –