2016-12-12 8 views
0

割り込みINT 1Ah/AH = 00hで時間(時、分、秒)を取得したいとします。私はそれがCXのクロック数の上位部分とDXのクロック数の下位部分を保持していることを知っています。アセンブリのBIOS割り込みでシステム時間を取得

私はそれについて検索し、次の式は、クロックが に一日の時間をカウント変換が見つかりました:

       Hour  = Clock/65543 (1007h) 
          Remainder = Clock MOD 65543 

          Minutes = Remainder/1092 (444h) 
          Remainder = Remainder MOD 1092 

          Second = Remainder/18.21 
          Remainder = Remainder MOD 18.21 

しかし、私はCXからクロックを得ることができますどのように、それらを使用する方法について混乱していますし、 DX?変数を読み込むべきですか?

答えて

1

割り込みを使用しないでください。を代わりに使用してください。あなたが主張するならば、Clockは、CXDXから形成されたちょうど32ビット値であることに注意してください。それらを変数に入れることは、まったく役に立たないでしょう。あなたはそれを分割する必要があるので、(高)とAX(低)の配当を期待しているDIV命令では少しだけシャッフルする必要があります。あなたは18.21で除算する際に問題に遭遇します。このようなものはうまくいくかもしれませんが、定数1092も正確ではありません。あなたが不運であれば(clock mod 65543はあなたに60を与える1092で割る、65519より上であることを起こる場合。)あなたは分間60で終わるかもしれない

mov ax, dx   ; low 16 bits 
mov dx, cx   ; high 16 bits 
div word [mem_65543] ; constant in memory 
mov [hours], ax 
mov ax, dx   ; work with remainder 
xor dx, dx   ; zero top bits 
div word [mem_1092] ; constant in memory 
mov [minutes], ax 
mov ax, [mem_100] ; constant in memory 
mul dx    ; scale by 100 
div word [mem_1821] ; constant in memory 
mov [seconds], ax 
+0

Iは、INT 1AH/02を試して、私はエラー得た:「INT 1AH、AH = 02Hを - サポートされている割り込みのリストを参照してください」 - emu8086を使用しています。 – Tom

+0

最後の除算を100( "スケールバック")にするのはなぜですか?秒はすでに 'AX'レジスタに入っています。 –

+1

@SepRoland dunno、brain fart? :)ありがとう! – Jester

1

EMU8086はほとんど8254タイマ0を、エミュレートされたことが表示されます

:時/分/秒(切り捨て)にダニの正確な変換のため

8254 channel 0 runs at 1.19318 mhz or ~ 838.0965 nsecs/cycle 
    System timer interrupts every 65536 cycles ~= 54.9255 ms 
    or ~ 18.20648 ticks per second 
    1 ms = 1193.18 cycles 
    1 hour ~= 65543 ticks ~= 3599.9816 secs 
    24 hour ~= 1573040 (hex 1800B0) ticks ~= 86399.998 secs 

例Cコード:PCシステムは、依然としてタイミング値であり、ここで、エミュレート

32ビット×16ビットの乗算ルーチンでは、フロア((2^32)/除数)で乗算することができます。 32×32ビット乗算ルーチンに

uint32_t i, tick, hour, minute, second; 
/* ... */ 
    i = tick<<10; 
    hour = (uint32_t)(((uint64_t)i*63)>>32); 
    i -= hour*67116375; 
    if(i >= 67116375){ 
     hour++; 
     i -= 67116375; 
    } 
    i <<= 4; 
    minute = (uint32_t)(((uint64_t)i*239)>>32); 
    i -= minute*17897700; 
    if(i >= 17897700){ 
     minute++; 
     i -= 17897700; 
    } 
    second = (uint32_t)(((uint64_t)i*14398)>>32); 
    i -= second*298295; 
    if(i >= 298295){ 
     second++; 
     i -= 298295; 
    } 

、単一減算チェックを省略することができる。

i = tick<<10; 
    hour = (uint32_t)(((uint64_t)i*2147243323u)>>57); 
    i -= hour*67116375; 
    i <<= 4; 
    minute = (uint32_t)(((uint64_t)i*4026081231u)>>56); 
    i -= minute*17897700; 
    second = (uint32_t)(((uint64_t)i*1887225577u)>>49); 
    i -= second*298295; 
関連する問題