Existem algumas interrupções que são criadas pelo próprio BIOS do sistema. Vamos ver algumas delas aqui.
BIOS — Basic Input/Output System — é o firmware da placa-mãe responsável pela inicialização do hardware. Ele quem começa o processo de boot do sistema além de anteriormente fazer um teste rápido (POST — Power-On Self Test) para verificar se o hardware está funcionando apropriadamente.
BIOS é um sistema legado de boot, sistemas mais modernos usam UEFI para o processo de boot do sistema.
Mas além de fazer essa tarefa de inicialização do PC ele também define algumas interrupções que podem ser usadas pelo software em real mode para tarefas básicas. E é daí que vem seu nome, já que essas tarefas são operações básicas de entrada e saída de dados para o hardware.
Cada interrupção não faz um procedimento único mas sim vários procedimentos relacionados à um determinado hardware. Qual procedimento especificamente será executado é, na maioria das vezes, definido no registrador AH
ou AX
.
Essa interrupção tem procedimentos relacionados ao vídeo, como a escrita de caracteres na tela ou até mesmo alterar o modo de vídeo.
O procedimento INT 0x10 / AH 0x0E simplesmente escreve um caractere na tela em modo teletype, que é um nome chique para dizer que o caractere é impresso na posição atual do cursor e atualiza a posição do mesmo. É algo bem semelhante ao que a gente vê sob um sistema operacional usando uma função como putchar()
em C.
Esse procedimento recebe como argumento no registrador AL
o caractere a ser impresso e em BH
o número da página.
O número da página varia entre 0 e 7. São 8 páginas diferentes que podem ser apresentadas para o monitor como o conteúdo da tela. Por padrão é usada a página 0 mas você pode alternar entre as páginas fazendo com que conteúdo diferente seja apresentado na tela sem perder o conteúdo da outra página.
Se você já usou o MS-DOS deve ter visto programas, como editores de código, que imprimiam uma interface de texto (TUI) mas depois que finalizava o conteúdo do prompt voltava para a tela. Esses programas basicamente alternavam de página.
No exemplo acima usamos a interrupção duas vezes para imprimir dois caracteres diferentes, fazendo assim um "Hello World" de míseros 11 bytes.
Poderíamos fazer um procedimento para escrever uma string inteira usando um loop. Ficaria assim:
Esse procedimento seta a posição do cursor em uma determinada página.
Pega a posição atual do cursor na página especificada. Retornando:
Alterna para a página especificada por AL que deve ser um número entre 0 e 7.
Imprime o caractere AL na posição atual do cursor CX vezes, sem atualizar o cursor. BL é o atributo do caractere que será explicado mais embaixo.
Mesma coisa que o procedimento anterior porém mudando somente que não é especificado um atributo para o caractere.
Esse procedimento imprime uma string na tela podendo ser especificado um atributo. O modo de escrita pode variar entre 0 e 3, se trata de 2 bits especificando duas informações diferentes:
No caso do segundo bit, se estiver ligado então o procedimento irá ler a string considerando que se trata de uma sequência de caractere e atributo. Assim cada caractere pode ter um atributo diferente. Conforme exemplo abaixo:
Os procedimentos 0x0E e 0x13 interpretam caracteres especiais como determinadas ações que devem ser executadas ao invés de imprimir o caractere na tela. Cada caractere faz uma ação diferente conforme tabela abaixo:
Você pode combinar 0x0D e 0x0A para fazer uma quebra de linha.
Os procedimentos definidos nessa interrupção são todos relacionados à entrada do teclado. Toda vez que o usuário pressiona uma tecla ela é lida e armazenada no buffer do teclado. Se você tentar ler do buffer sem haver dados lá, então o sistema irá ficar esperando o usuário inserir uma entrada.
Lê um caractere do buffer do teclado e o remove de lá. Retorna os seguintes valores:
Scancode é um número que identifica a tecla e não especificamente o caractere inserido.
Verifica se há um caractere disponível no buffer sem removê-lo de lá. Se houver caractere disponível, retorna:
O procedimento também modifica a Zero Flag para especificar se há ou não caractere disponível. A define para 0 se houver, caso contrário para 1.
Você pode usar em seguida o AH 0x00 para remover o caractere do buffer, se assim desejar. Desse jeito é possível pegar um caractere sem fazer uma pausa.
Pega status relacionados ao teclado. É retornado em AL 8 flags diferentes, cada uma especificando informações diferentes sobre o estado atual do teclado. Conforme tabela:
Quando o sistema está em modo texto a memória onde se armazena os caracteres começa no endereço 0xb800:0x0000 e ela é estruturada da seguinte forma:
Ou seja começando em 0xb800:0x0000 as páginas estão uma atrás da outra na memória como uma grande array.
O caractere nada mais é que o código ASCII do mesmo, já o atributo é um valor usado para especificar informações de cor e blink do caractere.
Os 4 bits (nibble) mais significativo indicam o atributo do fundo e os 4 bits menos significativos o atributo do texto, gerando uma cor na escala RGB. Caso não conheça essa é a escala de cor da luz onde as cores primárias Red (vermelo), Green (verde) e Blue (azul) são usadas em conjunto para formar qualquer outra cor. Conforme figura abaixo podemos ver qual bit significa o quê:
O bit de intensidade no atributo de texto, caso ligado, faz com que a cor do texto fique mais viva enquanto desligado as cores são mais escuras. Já o bit de blink especifica se o texto deve permanecer piscando. Caso ativo o texto ficará aparecendo e desaparecendo da tela constantemente.
Um exemplo de "Hello World" usando alguns conceitos apresentados aqui:
Para uma lista completa de todas as interrupções definidas pelo BIOS, sugiro a leitura:
AH
BH
DH
DL
0x02
Página
Linha
Coluna
AH
BH
0x03
Página
CH
CL
DH
DL
Scanline inicial
Scanline final
Linha
Coluna
AH
AL
0x05
Página
AH
AL
BH
BL
CX
0x09
Caractere
Página
Atributo
Vezes para imprimir o caractere
AH
AL
BH
CX
0x0A
Caractere
Página
Vezes para imprimir
Registrador
Parâmetro
AL
Modo de escrita
BH
Página
BL
Atributo
CX
Tamanho da string (número de caracteres a serem escritos)
DH
Linha
DL
Coluna
ES:BP
Endereço da string
Bit
Informação
0
Se ligado atualiza a posição do cursor.
1
Se desligado BL é usado para definir o atributo. Se ligado, o atributo é lido da string.
Caractere
Nome
Seq. de escape
Ação
0x07
Bell
\a
Emite um beep.
0x08
Backspace
\b
Retorna o cursor uma posição.
0x09
Horizontal TAB
\t
Avança o cursor 4 posições.
0x0A
Line feed
\n
Move o cursor verticalmente para a próxima linha.
0x0D
Carriage return
\r
Move o cursor para o início da linha.
Registrador
Valor
AL
Código ASCII do caractere
AH
Scancode da tecla.
Registrador
Valor
AL
Código ASCII
AH
Scancode
Bit
Flag
0
Tecla shift direita está pressionada.
1
Tecla shift esquerda está pressiona.
2
Tecla ctrl está pressionada.
3
Tecla alt está pressionada.
4
Scroll lock está ligado.
5
Num lock está ligado.
6
Caps lock está ligado.
7
Modo Insert está ligado.