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) 


Fazendo a leitura de setores

Está na hora de fazer a leitura de alguns setores do disco. Como não temos um sistema operacional ativado (o nosso é que está sendo), precisamos usar interrupções da BIOS. Dê uma olhada no helpPC: escolha "BIOS disk services" e garanto que você há de concordar: a INT 13 é perfeita.

Ressetando o sistema de disco

É interessante referir que, antes de começar a fazer uma leitura de dados, convém ressetar a controladora de disco. Ainda no helpPC, escolha o serviço 0 da INT 13, "Reset disk system". Esta interrupção precisa dos parâmetros AH=0 e DL com o número identificador do disco: 0=drive A; 1=segundo drive de disquete; 80h=drive 0 e 81h=drive 1. Como já armazenamos o número do drive na variável bootdrv, basta referenciá-la. Além disto, esta interrupção tem valores de retorno: AH=status da operação do disco e a flag de carry CF=0 (zero indica sucesso) ou 1 (1 indica erro).

A rotina que teremos pela frente será um tanto longa. Para manter o código legível, é aconselhável criar uma função, que chamaremos de carregar. A primeira rotina desta função será ressetar a controladora de disco:

... ; --------------------------------------------------------- ; Funções e variáveis do nosso bootstrap ; ---------------------------------------------------------- bootdrv db 0 ; A identificação do drive de boot <--- RESSETANDO O SISTEMA DE DISCO carregar: push ds ; Preserva o valor do segmento de dados na pilha .reset: mov ax, 0 ; Serviço que reseta o sistema de disco mov dl, [bootdrv] ; Drive que deve ser resetado int 13h ; INT 13 faz o reset jc .reset ; Falhou -> Tentar novamente (jc=jump on carry) pop ds ; Retoma o valor do segmento de dados da pilha

Observe que, se o sistema não puder ser ressetado devido a uma falha física do disco ou outra razão qualquer, nosso loader vai pendurar no loop .reset <-> jc .reset. Futuramente poderemos corrigir esta falha potencial. Outra novidade é o marcador precedido por um ponto (.reset:). Este ponto indica que o marcador é local e pertence à área do marcador carregar, ou seja, fora desta área ele não pode ser referenciado (mesmo porque não funcionará).

Fazendo a leitura de setores

Se tudo correr bem, está na hora de fazer a leitura dos setores. Faremos a leitura de 5 setores usando outro serviço da INT 13. O serviço 2 desta interrupção é o "Read Disk Sectors" e precisa dos seguintes parâmetros: AH=2 para indicar o serviço, AL=número de setores a serem lidos, CH=trilha/cilindro do disco, CL=número do setor, DH=número da cabeça, DL=número do drive e ES:BX como ponteiro para um buffer. Os valores de retorno da INT 13,2 são: AH=status da operação do disco, AL=número de setores lidos e a flag de carry CF=0 (zero indica sucesso) ou 1 (1 indica erro).

... ; --------------------------------------------------------- ; Funções e variáveis do nosso bootstrap ; ---------------------------------------------------------- bootdrv db 0 ; A identificação do drive de boot carregar: push ds ; Preserva o valor do segmento de dados na pilha .reset: mov ax, 0 ; Serviço que reseta o sistema de disco mov dl, [bootdrv] ; Drive que deve ser resetado int 13h ; INT 13 faz o reset jc .reset ; Falhou -> Tentar novamente (jc=jump on carry) pop ds ; Retoma o valor do segmento de dados da pilha <--- ADICIONANDO A LEITURA .leitura: mov ax,0x1000 ; O buffer deve ficar em 1000:0000 mov es,ax ; Transfere 1000 para ES (Extra Segment) mov bx, 0 ; e transfere 0 de deslocamento para BX ; O resultado é ES:BX com 1000:0000 mov ah, 2 ; Serviço 2 da INT 13 => Ler setores de disco mov al, 5 ; Ler 5 setores (é mais do que suficiente) mov cx, 2 ; Cilindro=0, Setor=2 mov dh, 0 ; Cabeça=0 mov dl, [bootdrv] ; Drive=drive de boot int 13h ; Leia! ES:BX = dados do disco jc .leitura ; falhou -> Tente novamente retn ; Terminada a leitura, retornar

Até já sei... você se embananou com cilindro, setor e cabeça. Por enquanto, deixa quieto. O importante é que tenha compreendido o restante do código.

Informações adicionais