2017-06-02 11 views
2

私はDOSOSを使ってアセンブリ8086の学校プロジェクトに取り掛かりました。私はプログラムを0.5秒遅らそうとしていました。int 21hとah = 2Chを使った遅延プログラム

mov ah, 2Ch 
int 21h 
mov al, dl ;hundredths 
mov bx, 0 
wait_loop: 
    one_hun: 
     int 21h 
     cmp al, dl 
     je one_hun 
    mov al, dl 
    inc bx 
    cmp bx, 50 
    jne wait_loop 

答えて

4

...私はDLで百分の値を持つ関数歴、int型の21Hを使用して、初期時刻に現在の時刻を比較するループを作成しようとしましたが、遅すぎるように思わ私はむしろBIOS int 1Ahを使用しています。これは、int 21hサービスのソースとして使用されています。これは少し使いやすいかもしれません。

しかし、デフォルトでは注意してください(タイマーチップを再プログラムする予定がない限り)。これは1秒間に18.2回になるので、0.5秒間待機するには9(cca。440〜494.51ms)または10 495〜549.45ms)のチックでは、精度はデフォルトの±50msに制限されます)。

タイマーチップを再プログラムする場合は、少し高い精度が得られるかもしれませんが、DOSでは(おそらく最新のOSでエミュレートされているように)十万秒が完全に確実に動作するとは思われません。

あなたの現在のコードについて

dlで百分の一ずつ増加されていないので、あなたはそれらの18.2Hzの数ティックbxでカウントされている、いない百(つまり、あなたのコードは〜2.7sのを待ち、 右?)。

はまた、何らかの理由(OSはしばらくの間、あなたのコードを実行しなかった)のためにその正確な100分の50差を逃した場合、あなたはループを作成しますので、条件<=または>=を行い、常に、同様のコードでjeをしませんこれはほぼ無限に実行されます(オーバーフローの1つの後に偶発的に50になるまで)。それをあなたの方法を行うには

、あなたがデルタを計算する必要があります。

mov ah, 2Ch 
    int 21h 
    mov al, dl ;hundredths 
wait_loop: 
     nop  ; burn the CPU a bit less 
     int 21h 
     sub dl,al ; calculate delta of hundredths (-99..+99) 
     jnc delta_positive 
     add dl,100 ; adjust the delta to be positive 1-99 
delta_positive: 
     cmp dl,50 
     jb wait_loop 
+0

は、問題を解決し、ありがとうございます! – Shelly

+0

彼らはどのようにして1秒あたり18.2回を決定しましたか?奇妙に思える。 – fuz

+4

@fuzは基本的に完全な16/32ビットオーバーフロー(65536/18.2 =〜3600 = 1時間)と初期クリスタル周波数を加算します:https://blogs.msdn.microsoft.com/oldnewthing/20041202-00/?p= 37153 – Ped7g

関連する問題