Recherche…


Appels du BIOS

Comment interagir avec le BIOS

Le système d'entrée / sortie de base, ou BIOS, est ce qui contrôle l'ordinateur avant tout système d'exploitation. Pour accéder aux services fournis par le BIOS, le code de l'assemblage utilise des interruptions . Une interruption prend la forme de

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

Le numéro d'interruption doit être compris entre 0 et 255 (0x00 - 0xFF) inclus.

La plupart des appels du BIOS utilisent le registre AH comme paramètre de "sélection de fonction" et utilisent le registre AL comme paramètre de données. La fonction sélectionnée par AH dépend de l'interruption appelée. Certains appels du BIOS nécessitent un seul paramètre 16 bits dans AX , ou n'acceptent aucun paramètre, et sont simplement appelés par l'interruption. Certains ont encore plus de paramètres, qui sont passés dans d'autres registres.

Les registres utilisés pour les appels du BIOS sont fixes et ne peuvent pas être échangés avec d'autres registres.

Utiliser les appels du BIOS avec la fonction select

La syntaxe générale d'une interruption du BIOS utilisant un paramètre de sélection de fonction est la suivante:

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

Exemples

Comment écrire un caractère à l'écran:

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

Comment lire un personnage du clavier (blocage):

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

Comment lire un ou plusieurs secteurs à partir d'un disque externe (en utilisant l'adressage 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

Comment lire le système RTC (horloge temps réel):

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

Comment lire l'heure système du 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

Comment lire la date du système à partir du 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

Comment obtenir la taille de la mémoire basse contiguë:

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

Comment redémarrer l'ordinateur:

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.

La gestion des erreurs

Certains appels du BIOS peuvent ne pas être implémentés sur chaque machine et ne sont pas garantis pour fonctionner. Souvent, une interruption non 0x86 ou 0x80 dans le registre AH . À peu près toutes les interruptions placeront l'indicateur de retenue (CF) sur une condition d'erreur. Cela permet de passer facilement à un gestionnaire d'erreur avec le saut conditionnel jc . (Voir sauts conditionnels )

Les références

La liste d'interruptions de Ralf Brown contient une liste assez exhaustive d'appels du BIOS et d'autres interruptions. Une version HTML peut être trouvée ici .

Les interruptions souvent supposées disponibles se trouvent dans une liste sur Wikipedia .

Un aperçu plus approfondi des interruptions couramment disponibles est disponible sur osdev.org



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow