Ricerca…


Chiamate del BIOS

Come interagire con il BIOS

Il Basic Input / Output System, o BIOS, è ciò che controlla il computer prima che venga eseguito qualsiasi sistema operativo. Per accedere ai servizi forniti dal BIOS, il codice assembly utilizza gli interrupt . Un interrupt assume la forma di

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

Il numero di interrupt deve essere compreso tra 0 e 255 (0x00 - 0xFF), compreso.

La maggior parte delle chiamate BIOS utilizza il registro AH come parametro "selezione funzione" e utilizza il registro AL come parametro di dati. La funzione selezionata da AH dipende dall'interrupt chiamato. Alcune chiamate BIOS richiedono un singolo parametro a 16 bit in AX o non accettano affatto i parametri e vengono semplicemente richiamate dall'interrupt. Alcuni hanno anche più parametri, che vengono passati in altri registri.

I registri utilizzati per le chiamate BIOS sono fissi e non possono essere scambiati con altri registri.

Utilizzando le chiamate del BIOS con la funzione select

La sintassi generale per un interrupt del BIOS che utilizza un parametro di selezione della funzione è:

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

Esempi

Come scrivere un personaggio sul display:

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

Come leggere un personaggio dalla tastiera (blocco):

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

Come leggere uno o più settori da un'unità esterna (utilizzando l'indirizzamento 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

Come leggere il sistema 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

Come leggere l'ora del sistema da 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

Come leggere la data di sistema da 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

Come ottenere dimensioni di memoria bassa contigua:

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

Come riavviare il computer:

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.

Gestione degli errori

Alcune chiamate BIOS potrebbero non essere implementate su ogni macchina e non è garantito il funzionamento. Spesso un interrupt non implementato restituirà 0x86 o 0x80 nel registro AH . Quasi ogni interrupt imposterà il flag di carry (CF) su una condizione di errore. Ciò semplifica il passaggio a un gestore di errori con il salto condizionale jc . (Vedi Salti condizionali )

Riferimenti

Un elenco piuttosto esauriente di chiamate BIOS e altri interrupt è l'Elenco interrupt di Ralf Brown . Una versione HTML può essere trovata qui .

Gli interrupt spesso presunti disponibili si trovano in un elenco su Wikipedia .

Una panoramica più approfondita delle interruzioni comunemente disponibili può essere trovata su osdev.org



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow