n*55ms
の実行を中止するプロシージャをINT 08h
を使用して作成しようとしていますが、これまでのところ有用なものが見つかりませんでした。
この割り込みはどのように使用しますか?x86アセンブリのタイマ割り込み
答えて
Ralph Browns Interrupt Listを参照すると、INT 08h
の関連情報が表示されます。
ご利用シナリオによっては、次の2つの選択肢の間で選択することができます。あなたの使用シナリオが何であれCPU-generated (80286+) - DOUBLE EXCEPTION DETECTED
- が、これは非常によくそれを説明しています。
INT 08h
には、ハードウェア割り込みまたはソフトウェア割り込みの2つの可能性があります。あなたの質問であなたがどちらを指しているのかははっきりしません。
基本的な考え方は、この割り込みのための既存のIVTエントリ(0x000:0x0020の4バイト)を取得してどこかに保存し、それらの4バイトを割り込みハンドラのセグメントとオフセットに置き換えることです。割り込みハンドラは1秒間に18.2回呼び出され、割り込みハンドラは古い割り込みハンドラに(最初に保存した4バイトを使用して)「遠くにジャンプ」する必要があります。
完了したら(たとえば、プログラムがDOSなどで終了した場合など)、元の4バイトを0x000:0x0020に復元します。
n*55 ms
の場合は、グローバル変数をn+1
に設定し、割り込みハンドラがそのグローバル変数をデクリメントします。グローバル変数が0にデクリメントされると、渡された時間はn*55 ms
と(n+1)*55 ms
の間にあることがわかります。
この精度の欠如は、割り込みハンドラをインストールしてから最初のIRQが発生するまでの時間のばらつきがあることに注意してください(たとえば、タイマのIRQは割り込みハンドラをインストールした直後に発生する可能性があります。割り込みハンドラをインストールしてください)。最初のタイマーIRQが発生するのを待ってからn*55 ms
のコードを実行させると、「正確に」n*55 ms
の後にコードを停止することができます。
また、割り込みハンドラが使用するレジスタ(セグメントレジスタを含む)が保存されていることを確認してから、 "jmp far"を実行する前にリストアしてください。レジスタを使用せずに値をデクリメントしてゼロと比較することができます(したがって、レジスタを使用せずに使用するレジスタの保存と復元を回避できます)。例(NASM)の場合:
interruptHandler:
sub word [cs:globalCounter],1
je .counterIsZero
jmp far [cs:oldInterruptHandler]
.counterIsZero:
あなたがINT 1Ah, AH=0サービスを通じて、または直接メモリアドレス0040h:006C
でint 08h
の出力を読み取ることができます。
; 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
(ちょうど頭からそれを書いた私は、それをデバッグしていないので、保証は、それが動作しません)
をプラス多分それは、(ビューの電力使用量の観点から)いいだろうが、いくつか入れてそれらのループにnops ...それらの4-8のようなものです(これは、近年のx86では、cmp + jeがnopと同じくらい低電力である可能性が高いからです)。
最初の余分なループをコーディングするのではなく、単純に 'inc cx'ですか? – Tommylee2k
@ Tommylee2kは技術的には違います(cx = 0とは異なる動作)。実際には実際には、 "少なくともn * 55ms"よりも "0〜n * 55ms"の遅延が必要だと思うので、自分のコードでは最初のループを完全に削除します...しかし、アプリケーション私はVsyncにかなり同期していましたが、55msが60Hzのディスプレイでは長すぎるグラフィックスで通常作業していたので、18.2/sのティッカーはあまり役に立ちませんでした。 – Ped7g
論理的に私は0スリープされていない0スリープして3.6秒(この場合は私は0xffffを使用するだろう)ために "スリープ"と言われる関数を除いて、この変更も修正される;)しかし、wait()は私が使用しない機能。睡眠を必要とする今のプログラムは悪いデザインです(これは犯罪ではありません、sync'ingは眠っていません:-P) – Tommylee2k
- 1. x86:割り込みハンドラループ
- 2. マルチスレッドプログラムのC++タイマ割り込み
- 3. タイマ割り込みはNMI ..ですか?
- 4. x86割り込みテーブルの変更
- 5. オペレーティングシステムの割り込みのためのタイマ
- 6. 外部割り込み後のArduino WDTタイマ値
- 7. x86 CPUの割り込みレイテンシの見積もり
- 8. nRF52のタイマ割り込み内でI2C割り込みを有効にするArduino
- 9. Attiny85タイマ割り込みでグローバル変数を使用する
- 10. atmega 328p割り込みとタイマ設定[C/C++]
- 11. タイマ割り込みをマスクできますか?
- 12. 保護モードでの割り込みの設定(x86)
- 13. c/asmでの割り込みの再プログラミングx86
- 14. x86ハードウェア割り込みがqemuで動作しません
- 15. x86アセンブリ言語でのメモリ割り当て
- 16. アセンブリ内の割り込みコードを修正します。
- 17. アセンブリのBIOS割り込みでシステム時間を取得
- 18. x86アセンブリのバッファ
- 19. アセンブリのx86 -
- 20. 組み込みのDOSでx86リアルモードのキーボード割り込みサービスルーチンを設定してリセットする
- 21. x86アーキテクチャ用のLinuxカーネルでの割り込み処理コードの位置
- 22. x86-64 GNUアセンブリ
- 23. アセンブリx86 Win32
- 24. x86アセンブリ関数
- 25. アセンブリx86フラグ - オーバーフローフラグ
- 26. .NET - NGENのx86アセンブリ
- 27. TRAP、ソフトウェア割り込みとハードウェア割り込みの違いは?
- 28. 割り込みフラグと割り込み保留中のビットstm32
- 29. アレイの代わりにx86アセンブリ
- 30. 割り込みsuper.onCreate()
おそらく 'cli/sti'とそれ自身のIVT値をインストールすることに言及する価値があります。ちょうど2つの値をRAMに書き込むほど簡単ではないことを確認することです(そうでないためです)。 – Ped7g