Ich versuche, eine Prozedur zu schreiben, die die Ausführung für n*55ms
mit der INT 08h
stoppen wird, aber ich konnte bisher nichts nützliches finden.
Wie verwende ich diesen Interrupt?Timer-Interrupt in x86 Assembly
Antwort
Sie können auf Ralph Browns Interrupt List beziehen, um die relevanten Informationen für INT 08h
zu erhalten.
Je nach Einsatzszenario können Sie zwischen zwei Möglichkeiten wählen:
Was auch immer Ihr Einsatzszenario sein kann, dies es sehr gut erklärt.
So gibt es zwei Möglichkeiten für eine auftretende INT 08h
- eine Hardware oder ein Software-Interrupt. Es ist nicht klar, auf welche Sie sich mit Ihrer Frage bezogen haben.
Die Grundidee wäre, den vorhandenen IVT-Eintrag für diesen Interrupt (die vier Bytes bei 0x000: 0x0020) zu erhalten und irgendwo zu speichern, dann ersetzen Sie diese vier Bytes durch das Segment und den Offset Ihres Interrupt-Handlers. Ihr Interrupt-Handler wird 18.2 mal pro Sekunde aufgerufen, und Ihr Interrupt-Handler sollte "weit" zum alten Interrupt-Handler springen (mit den vier Bytes, die Sie ursprünglich gespeichert haben).
Wenn Sie fertig sind (z. B. ob/wann Ihr Programm zu DOS oder etwas zurückkehrt), würden Sie die ursprünglichen vier Bytes bei 0x000: 0x0020 wiederherstellen.
Für den Teil n*55 ms
würden Sie eine globale Variable auf n+1
setzen, und Ihr Interrupt-Handler würde diese globale Variable dekrementieren. Wenn die globale Variable auf 0 dekrementiert wurde, wissen Sie, dass die verstrichene Zeit zwischen n*55 ms
und (n+1)*55 ms
liegt. Beachten Sie, dass dieser Mangel an Genauigkeit auf die zeitliche Variabilität zwischen der Installation des Interrupt-Handlers und dem Auftreten des ersten IRQ zurückzuführen ist (z. B. der IRQ des Timers kann unmittelbar nach der Installation des Interrupt-Handlers oder bis zu 55 ms nach Ihnen auftreten) Installieren Sie Ihren Interrupt-Handler). Wenn Sie warten, bis der erste Zeitgeber-IRQ auftritt und dann Ihren Code für n*55 ms
ausgeführt wird, können Sie Ihren Code nach "genau" n*55 ms
stoppen.
Stellen Sie außerdem sicher, dass Ihr Interrupt-Handler alle verwendeten Register (einschließlich der Segmentregister) speichert und wiederherstellt, bevor Sie "jmp far" ausführen. Es ist möglich, einen Wert zu dekrementieren und mit Null zu vergleichen, ohne irgendwelche Register zu verwenden (und daher möglich, das Speichern und Wiederherstellen von Registern zu vermeiden, die Sie verwenden, weil Sie keine verwendet haben). Zum Beispiel (NASM):
interruptHandler:
sub word [cs:globalCounter],1
je .counterIsZero
jmp far [cs:oldInterruptHandler]
.counterIsZero:
Sie können die Ausgabe von int 08h
durch INT 1Ah, AH=0 Service oder direkt an der Speicheradresse 0040h:006C
lesen.
; cx = "n" to wait "at least n*55ms", will modify cx
DelayProcedure:
push ax
push ds
mov ax,40h
mov ds,ax
; make sure that the delay will take "at least n*55ms"
; by waiting for first incomplete (<= 55ms) tick
mov ax,[6Ch]
.waitFirstForOneTickHappen:
nop
cmp [6Ch],ax
je .waitFirstForOneTickHappen
; remove the loop above to get "at most n*55ms" behaviour
; (which may be more practical for some situations, like animation syncing)
; wait "at most n*55ms" ticks
.waitNticks:
mov ax,[6Ch]
.waitForTick:
nop
cmp [6Ch],ax
je .waitForTick
loop .waitNticks
; restore ds, ax and return
pop ds
pop ax
ret
(ich habe es nicht debuggen, nur um es von Kopf geschrieben, so dass keine Garantie wird es funktionieren)
plus vielleicht wäre es schön, (von dem Stromverbrauch Sicht) auf mehr setzen Nops in diese Schleifen ...wie 4-8 von ihnen (als wieder cmp + je ist sehr wahrscheinlich als Low-Power wie NOP auf modernen x86).
Könntest du nicht einfach "inc cx" anstelle der zusätzlichen Schleife am Anfang? – Tommylee2k
@ Tommylee2k technisch nicht (anderes Verhalten für Cx = 0), praktisch ja. Eigentlich denke ich, dass die "0 bis n * 55ms" Verzögerung mehr gewünscht ist, als "mindestens n * 55ms", also würde ich für meinen eigenen Code diese erste Schleife komplett entfernen ... Aber dann wieder, in meinem ganzen DOS Apps, die ich eher mit Vsync synchronisierte, war der 18.2/s-Ticker für mich nicht von großem Nutzen, da ich normalerweise mit Grafiken arbeitete, wo 55ms mit 60Hz Display zu lang waren. – Ped7g
logisch würde ich eine Funktion, die "Schlaf" für 0 x 55 ms gesagt wird, um 3,6 Sekunden nicht zu schlafen (für diesen Fall würde ich 0xffff verwenden), so dass diese Änderung wäre sogar eine Lösung;) aber warten() ist Funktionen, die ich nie benutze; Imo-Programme, die einen Schlaf brauchen, sind schlechtes Design (das ist nichts für ungut, Sync'ing schläft nicht :-P) – Tommylee2k
- 1. Modulus in Assembly x86
- 2. x86 Assembly-Idiome
- 3. Assembly Sprache x86 Irvine32
- 4. x86 Assembly Referenzblatt
- 5. LinkedList in Assembly x86 Irvine
- 6. Haltewinkel in x86 Intel Assembly
- 7. Assembly x86 Win32
- 8. Zugriffsverletzung MASM x86 Assembly
- 9. Assembly x86, Begrüßungsprogramm
- 10. Macht der Funktion x86 Assembly
- 11. x86 Assembly Force Cache Store
- 12. Führende Null in Zeichenerweiterung in x86-Assembly?
- 13. Laden x86 oder x64 Assembly
- 14. x86 Assembly add and shift
- 15. Quadratwurzelfunktion in Forth mit x86 Assembly?
- 16. Zweck der cmove-Anweisung in x86-Assembly?
- 17. Dynamische Variablenerstellung in der Baugruppe? (X86 Assembly)
- 18. Vergleichen Sie zwei Strings in x86 Assembly
- 19. Drucken Integer zu Konsole in x86-Assembly
- 20. Operand Größe Konflikt in x86 Assembly
- 21. Ausführungscode auf anderem Prozessor (x86-Assembly)
- 22. x86-64 Assembly "cmovge" zu C code
- 23. x86 Assembly extreme Anfänger Anfrage: "ungültige Befehlsoperanden"?
- 24. Zeichnen eines Stack-Frame für x86-Assembly
- 25. Geschützter Modus Tastaturzugriff auf x86 Assembly
- 26. Implementieren x86 zu x64 Assembly Code-Schalter
- 27. Assembly x86: Vergleichen von Zeichenfolgen funktioniert nicht
- 28. Convert x86 Assembly Jump-Tabelle C
- 29. x86 gcc assembly output hilfe bitte
- 30. Was macht diese x86 Inline-Assembly?
Vielleicht wäre es eine Erwähnung von 'cli/sti' zusammen mit der Installation eines eigenen IVT-Wertes wert. Nur um sicherzustellen, dass es nicht so einfach klingt wie das Schreiben von zwei Werten in den RAM (weil es nicht ist). – Ped7g