A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Oficina

12. O loader Numaboa II

Dom

27

Mai

2007


07:24

(7 votos, média 3.86 de 5) 


Maluco beleza MÓDULO 12 do SO Numaboa

Depois de dois módulos de pura teoria, está na hora de programar um pouco. Com os conhecimentos recém adquiridos (ou revisados), vamos dar uma melhorada no Sistema Operacional NumaBoa. Desta vez vamos criar um loader que carrega um programa a partir do disco e salta para ele. Aliás, é bom saber que existe um outro nome para o loader: é também chamado de bootstrap.

Desabilitando as interrupções

Sempre é aconselhável acertar a pilha antes de começar a fazer qualquer coisa. Como você já sabe, a pilha também é usada para armazenar valores temporários - PUSH põe um valor no topo da pilha e POP tira o valor do topo da pilha. Acontece que a pilha também é usada por instruções de chamada CALL, as quais colocam o endereço de retorno no topo da pilha. Além disto, quando ocorre uma interrupção, também é executada uma instrução de chamada. Este é o motivo pelo qual precisamos desabilitar as interrupções antes de configurar a pilha. Veja como fazê-lo no exemplo abaixo:

[ORG 7C00h] ; Onde a BIOS nos coloca ; --------------------------------------------------------- ; Programa principal ; --------------------------------------------------------- inicio: ; Configurar a pilha. ; Não podemos permitir interrupções durante a configuração cli ; Disabilitar interrupções mov ax, 0x9000 ; Por a pilha em 9000:0000 mov ss, ax ; Transferir o endereço para o registrador ; do segmento da pilha (SS) mov sp, 0 ; Zerar ponteiro do topo da pilha sti ; Habilitar interrupções (SeT Interrupts bit)

O mnemônico da instrução cli é CLear Interrupts, ou seja, CLarear (ou limpar) o bit de Interrupção. Zerando o bit de interrupção desabilita as chamadas. Em contrapartida, sti deriva de SeT Interrupts e habilita as chamadas.

O registrador do segmento da pilha não pode ser acessado diretamente para evitar erros devidos à falta de atenção. Forçando o programador a fazer transferências indiretas, a possibilidade de erros diminui muito. É por isto que transferimos o endereço desejado para a pilha (9000) inicialmente para AX e, num segundo passo, transferimos este valor para SS. Se você ainda se lembra do duplo endereço, sabe que 9000:0000 indica o segmento 9000 e deslocamento 0000. Colocamos então o deslocamento em SP com a instrução mov sp,0. Terminada a configuração da pilha, podemos habilitar novamente as interrupções.

Identificando o drive de boot

A BIOS costuma estar configurada para procurar setores de boot numa determinada sequência, digamos no drive de disquete e depois no HD. Se nosso sistema operacional estiver em disquete e o disquete estiver inserido no drive, o primeiro setor de boot a ser lido será o do disquete. E se não for este o caso? Qual foi o disco utilizado? Sempre é bom saber, para ficar com a faca e o queijo na mão. Para isto, criamos uma variável bootdrv e lhe atribuímos o valor da identificação do drive logo no início do programa. Sabendo que a identificação do drive de boot é colocada no registrador DX, na sua porção baixa DL, basta acrescentar o seguinte código:

[ORG 7C00h] ; Onde a BIOS nos coloca ; --------------------------------------------------------- ; Programa principal ; --------------------------------------------------------- inicio: ; Configurar a pilha. ; Não podemos permitir interrupções durante a configuração cli ; Disabilitar interrupções mov ax, 0x9000 ; Por a pilha em 9000:0000 mov ss, ax ; Transferir o endereço para o registrador ; do segmento da pilha (SS) mov sp, 0 ; Zerar ponteiro do topo da pilha sti ; Habilitar interrupções (SeT Interrupts bit) mov [bootdrv], dl <--- DL indica o drive de boot ... ; --------------------------------------------------------- ; Funções e variáveis do nosso bootstrap ; ---------------------------------------------------------- bootdrv db 0 <--- A identificação do drive de boot ...

Informações adicionais