サーチ…


BIOSコール

BIOSと対話する方法

BIOS(Basic Input / Output System)は、オペレーティングシステムが動作する前にコンピュータを制御するものです。 BIOSが提供するサービスにアクセスするために、アセンブリコードは割り込みを使用ます。割り込みは、

int <interrupt> ; interrupt must be a literal number, not in a register or memory

割り込み番号は0〜255(0x00〜0xFF)の間でなければなりません。

ほとんどのBIOSコールは、 AHレジスタを「ファンクション選択」パラメータとして使用し、 ALレジスタをデータパラメータとして使用します。 AHによって選択された機能は呼び出された割り込みに依存します。 BIOSの中には、 AXで1つの16ビット・パラメータが必要なものや、まったくパラメータを受け付けないものがあり、割り込みによって呼び出されるものがあります。いくつかのパラメータは、他のレジスタに渡されるさらに多くのパラメータを持っています。

BIOS呼び出しに使用されるレジスタは固定されており、他のレジスタと交換することはできません。

機能選択でBIOSコールを使用する

関数選択パラメータを使用したBIOS割り込みの一般的な構文は次のとおりです。

mov ah, <function>
mov al, <data>
int <interrupt>

キャラクターをディスプレイに書き込む方法:

mov ah, 0x0E             ; Select 'Write character' function
mov al, <char>           ; Character to write
int 0x10                 ; Video services interrupt

キーボードから文字を読む方法(ブロックする):

mov ah, 0x00             ; Select 'Blocking read character' function
int 0x16                 ; Keyboard services interrupt
mov <ascii_char>, al     ; AL contains the character read
mov <scan_code>, ah      ; AH contains the BIOS scan code

外部ドライブから1つまたは複数のセクタを読み取る方法(CHSアドレッシングを使用):

mov ah, 0x02             ; Select 'Drive read' function
mov bx, <destination>    ; Destination to write to, in ES:BX
mov al, <num_sectors>    ; Number of sectors to read at a time
mov dl, <drive_num>      ; The external drive's ID
mov cl, <start_sector>   ; The sector to start reading from
mov dh, <head>           ; The head to read from
mov ch, <cylinder>       ; The cylinder to read from
int 0x13                 ; Drive services interrupt
jc <error_handler>       ; Jump to error handler on CF set

システムの読み込み方法RTC(Real Time Clock):

mov ah, 0x00             ; Select 'Read RTC' function
int 0x1A                 ; RTC services interrupt
shl ecx, 16              ; Clock ticks are split in the CX:DX pair, so shift ECX left by 16...
or cx, dx                ; and add in the low half of the pair
mov <new_day>, al        ; AL is non-zero if the last call to this function was before midnight
                         ; Now ECX holds the clock ticks (approx. 18.2/sec) since midnight
                         ; and <new_day> is non-zero if we passed midnight since the last read

RTCからシステム時間を読み取る方法:

mov ah, 0x02             ; Select 'Read system time' function
int 0x1A                 ; RTC services interrupt
                         ; Now CH contains hour, CL minutes, DH seconds, and DL the DST flag,
                         ; all encoded in BCD (DL is zero if in standard time)
                         ; Now we can decode them into a string (we'll ignore DST for now)

mov al, ch               ; Get hour
shr al, 4                ; Discard one's place for now
add al, 48               ; Add ASCII code of digit 0
mov [CLOCK_STRING+0], al ; Set ten's place of hour
mov al, ch               ; Get hour again
and al, 0x0F             ; Discard ten's place this time
add al, 48               ; Add ASCII code of digit 0 again
mov [CLOCK_STRING+1], al ; Set one's place of hour

mov al, cl               ; Get minute
shr al, 4                ; Discard one's place for now
add al, 48               ; Add ASCII code of digit 0
mov [CLOCK_STRING+3], al ; Set ten's place of minute
mov al, cl               ; Get minute again
and al, 0x0F             ; Discard ten's place this time
add al, 48               ; Add ASCII code of digit 0 again
mov [CLOCK_STRING+4], al ; Set one's place of minute

mov al, dh               ; Get second
shr al, 4                ; Discard one's place for now
add al, 48               ; Add ASCII code of digit 0
mov [CLOCK_STRING+6], al ; Set ten's place of second
mov al, dh               ; Get second again
and al, 0x0F             ; Discard ten's place this time
add al, 48               ; Add ASCII code of digit 0 again
mov [CLOCK_STRING+7], al ; Set one's place of second
...
db CLOCK_STRING "00:00:00", 0   ; Place in some separate (non-code) area

RTCからシステム日付を読み取る方法:

mov ah, 0x04             ; Select 'Read system date' function
int 0x1A                 ; RTC services interrupt
                         ; Now CH contains century, CL year, DH month, and DL day, all in BCD
                         ; Decoding to a string is similar to the RTC Time example above

連続した低メモリのサイズを取得する方法:

int 0x12                 ; Conventional memory interrupt (no function select parameter)
and eax, 0xFFFF          ; AX contains kilobytes of conventional memory; clear high bits of EAX
shl eax, 10              ; Multiply by 1 kilobyte (1024 bytes = 2^10 bytes)
                         ; EAX contains the number of bytes available from address 0000:0000

コンピュータを再起動する方法:

int 0x19                 ; That's it! One call. Just make sure nothing has overwritten the
                         ; interrupt vector table, since this call does NOT restore them to the
                         ; default values of normal power-up. This means this call will not
                         ; work too well in an environment with an operating system loaded.

エラー処理

一部のBIOSコールは、すべてのマシンでインプリメントされない場合があり、動作することが保証されていません。多くの場合、実装されていない割り込みは、レジスタAH 0x86または0x80いずれかを返します。 ちょうどすべての割り込みが、エラー状態にキャリーフラグ(CF)を設定します。これにより、 jc条件ジャンプでエラーハンドラにジャンプするのが容易になります。 (「 条件ジャンプ 」を参照)

参考文献

BIOSコールや他の割り込みの網羅的なリストは、 Ralf BrownのInterrupt Listです。 HTML版がここにあります

利用可能と思われることが多い割り込みは、 Wikipediaのリストにあります。

一般的に利用可能な割り込みの詳細については、 osdev.orgを参照してください。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow