Buscar..


Llamadas del BIOS

Cómo interactuar con la BIOS

El sistema básico de entrada / salida, o BIOS, es lo que controla la computadora antes de que se ejecute cualquier sistema operativo. Para acceder a los servicios proporcionados por el BIOS, el código de ensamblaje utiliza interrupciones . Una interrupción toma la forma de

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

El número de interrupción debe estar entre 0 y 255 (0x00 - 0xFF), inclusive.

La mayoría de las llamadas del BIOS usan el registro AH como un parámetro de "selección de función", y usan el registro AL como un parámetro de datos. La función seleccionada por AH depende de la interrupción llamada. Algunas llamadas de BIOS requieren un solo parámetro de 16 bits en AX , o no aceptan parámetros en absoluto, y son simplemente llamadas por la interrupción. Algunos tienen incluso más parámetros, que se pasan en otros registros.

Los registros utilizados para las llamadas del BIOS son fijos y no pueden intercambiarse con otros registros.

Usando llamadas del BIOS con función de selección

La sintaxis general para una interrupción de BIOS usando un parámetro de selección de función es:

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

Ejemplos

Cómo escribir un carácter en la pantalla:

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

Cómo leer un carácter desde el teclado (bloqueo):

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

Cómo leer uno o más sectores desde una unidad externa (utilizando el direccionamiento 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

Cómo leer el 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

Cómo leer la hora del sistema desde el 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

Cómo leer la fecha del sistema desde el 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

Cómo obtener el tamaño de memoria baja 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

Cómo reiniciar la computadora:

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.

Manejo de errores

Es posible que algunas llamadas de BIOS no se implementen en todas las máquinas y no se garantiza que funcionen. A menudo, una interrupción no implementada devolverá 0x86 o 0x80 en el registro AH . Casi todas las interrupciones establecerán el indicador de acarreo (CF) en una condición de error. Esto facilita saltar a un controlador de errores con el salto condicional jc . (Ver saltos condicionales )

Referencias

Una lista bastante exhaustiva de llamadas del BIOS y otras interrupciones es la Lista de interrupciones de Ralf Brown . Una versión HTML se puede encontrar aquí .

Las interrupciones que a menudo se asume que están disponibles se encuentran en una lista en Wikipedia .

Puede encontrar una descripción más detallada de las interrupciones comúnmente disponibles en osdev.org



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow