Oficina
6. O setor de boot
|
Sab 26 Mai 2007 14:48 |
- Detalhes
- Categoria: Sistemas Operacionais
- Atualização: Domingo, 12 Abril 2009 12:30
- Autor: vovó Vicki
- Acessos: 17558
Pagina 3 de 5
O programa do setor de boot desassemblado
A seguir, o código em Assembly do programa do setor de boot. É um tanto extenso, mas vale a pena dar uma olhada. Não se preocupe se não identificar todas as instruções utilizadas. À medida que avançarmos nos tutoriais, elas serão referenciadas.
INICIO: INÍCIO DO PROGRAMA DO SETOR DE BOOT
0000:7C3E FA CLI desliga as interrupções
0000:7C3F 33C0 XOR AX,AX zera AX
0000:7C41 8ED0 MOV SS,AX SS agora é zero
0000:7C43 BC007C MOV SP,7C00 SP agora é 7C00
0000:7C46 16 PUSH SS põe zero na pilha
0000:7C47 07 POP ES e zera ES
O vetor da INT 1E etá em 0000:0078.
Pega o endereço apontado pelo vetor
e o coloca nos registradores DS:SI.
0000:7C48 BB7800 MOV BX,0078 BX agora é 78
0000:7C4B 36 SS:
0000:7C4C C537 LDS SI,[BX] DS:SI agora é [0:78]
0000:7C4E 1E PUSH DS salva DS:SI --
0000:7C4F 56 PUSH SI salva end tab param
0000:7C50 16 PUSH SS salva SS:BX --
0000:7C51 53 PUSH BX salva end da INT 1E
Move a tabela de parâmetros do
disquete para 0000:7C3E.
0000:7C52 BF3E7C MOV DI,7C3E DI é o endereço de START
0000:7C55 B90B00 MOV CX,000B contador é 11
0000:7C58 FC CLD limpa a direção
0000:7C59 F3 REPZ move a tabela de parâmetros
0000:7C5A A4 MOVSB do disquete para 0000:7C3E
0000:7C5B 06 PUSH ES também zera
0000:7C5C 1F POP DS DS
Altera alguns dados da tabela de
parâmetros do disquete.
0000:7C5D C645FE0F MOV BYTE PTR [DI-02],0F muda o tempo de ajuste
da cabeça em 0000:7C47
0000:7C61 8B0E187C MOV CX,[7C18] setores por trilha
0000:7C65 884DF9 MOV [DI-07],CL salva em 0000:7C42
Muda INT 1E para que aponte para a tabela de
parâmetros do disquete alterada em 0000:7C3E
0000:7C68 894702 MOV [BX+02],AX muda segmento da INT 1E
0000:7C6B C7073E7C MOV WORD PTR [BX],7C3E muda deslocamento
da INT 1E
Chama INT 13 com AX=0000, reset de disco, de
modo que a nova tabela de parâmetros do
disquete seja usada.
0000:7C6F FB STI liga as interruções
0000:7C70 CD13 INT 13 faz chamada do reset do
disquete
0000:7C72 7279 JB TALK salta se houver erro
Detemina o endereço inicial do setor do
diretório raiz como um LBA.
0000:7C74 33C0 XOR AX,AX AX agora é zero
0000:7C76 3906137C CMP [7C13],AX néumero de setores zero?
0000:7C7A 7408 JZ SMALL_DISK sim
0000:7C7C 8B0E137C MOV CX,[7C13] número de setores
0000:7C80 890E207C MOV [7C20],CX salva em número gigante
DISCO_PEQUENO:
0000:7C84 A0107C MOV AL,[7C10] número de tabelas FAT
0000:7C87 F726167C MUL WORD PTR [7C16] número de setores FAT
0000:7C8B 03061C7C ADD AX,[7C1C] nro de setores escondidos
0000:7C8F 13161E7C ADC DX,[7C1E] nro de setores escondidos
0000:7C93 03060E7C ADD AX,[7C0E] nro de setores reservados
0000:7C97 83D200 ADC DX,+00 nro de setores reservados
0000:7C9A A3507C MOV [7C50],AX salva endereço inicial
0000:7C9D 8916527C MOV [7C52],DX do dir raiz (como LBA)
0000:7CA1 A3497C MOV [7C49],AX salva endereço inicial
0000:7CA4 89164B7C MOV [7C4B],DX do dir raiz (como LBA)
Determina o endereço de setor do primeiro
setor na área de dados como um LBA.
0000:7CA8 B82000 MOV AX,0020 tamanho de uma entrada de
diretório (32)
0000:7CAB F726117C MUL WORD PTR [7C11] nro de entradas do
diretório raiz
0000:7CAF 8B1E0B7C MOV BX,[7C0B] bytes por setor
0000:7CB3 03C3 ADD AX,BX
0000:7CB5 48 DEC AX
0000:7CB6 F7F3 DIV BX
0000:7CB8 0106497C ADD [7C49],AX soma ao endereço inicial
0000:7CBC 83164B7C00 ADC WORD PTR [7C4B],+00 do dir raiz (como LBA)
Transfere o primeiro setor do diretório raiz
para 0000:0500.
0000:7CC1 BB0005 MOV BX,0500 end para transferência
0000:7CC4 8B16527C MOV DX,[7C52] pega end inicial do
0000:7CC8 A1507C MOV AX,[7C50] dir raiz (como LBA)
0000:7CCB E89200 CALL CONVERT chama rotina de
conversão
0000:7CCE 721D JB TALK salta se houver erro
0000:7CD0 B001 MOV AL,01 ler 1 setor
0000:7CD2 E8AC00 CALL READ_SECTORS lê primeiro setor do
diretório raiz
0000:7CD5 7216 JB TALK salta se houver erro
0000:7CD7 8BFB MOV DI,BX end da primeira entrada
do diretório
0000:7CD9 B90B00 MOV CX,000B contador é 11
0000:7CDC BEE67D MOV SI,7DE6 end dos nomes de arquivos
0000:7CDF F3 REPZ é o "IO.SYS"?
0000:7CE0 A6 CMPSB
0000:7CE1 750A JNZ TALK não
0000:7CE3 8D7F20 LEA DI,[BX+20] end da próxima entrada do
diretório
0000:7CE6 B90B00 MOV CX,000B contador é 11
0000:7CE9 F3 REPZ é o "MSDOS.SYS"?
0000:7CEA A6 CMPSB
0000:7CEB 7418 JZ FOUND_FILES são iguais
FALA:
Mostra mensagem "Non-System disk...",
espera usuário apertar uma tecla, restaura
o vetro da INT 1E e depois chama a INT 19
para iniciar o processo de boot novamente.
0000:7CED BE9E7D MOV SI,7D9E "Non-System disk..."
0000:7CF0 E85F00 CALL MSG_LOOP mostra mensagem
0000:7CF3 33C0 XOR AX,AX função INT 16
0000:7CF5 CD16 INT 16 lê teclado
0000:7CF7 5E POP SI pega o endereço do
0000:7CF8 1F POP DS vetor da INT 1E
0000:7CF9 8F04 POP [SI] restaura os dados do
0000:7CFB 8F4402 POP [SI+02] vetor da INT 1E
0000:7CFE CD19 INT 19 chama INT 19 para tentar
novamente
PREPARA_FALA:
0000:7D00 58 POP AX tira lixo da pilha
0000:7D01 58 POP AX tira lixo da pilha
0000:7D02 58 POP AX tira lixo da pilha
0000:7D03 EBE8 JMP TALK agora fala com o usuário
ARQUIVOS_ENCONTRADOS:
Trata o endereço de setor do primeiro setor
de IO.SYS.
0000:7D05 8B471A MOV AX,[BX+1A] pega nro do cluster
inicial
0000:7D08 48 DEC AX subtrai 1
0000:7D09 48 DEC AX subtrai 1
0000:7D0A 8A1E0D7C MOV BL,[7C0D] setores por cluster
0000:7D0E 32FF XOR BH,BH
0000:7D10 F7E3 MUL BX multiplica
0000:7D12 0306497C ADD AX,[7C49] adiciona o end inicial
0000:7D16 13164B7C ADC DX,[7C4B] do dir raiz (como LBA)
Transfere IO.SYS para a memória em 0000:0700.
IO.SYS tem comprimento de 3 setores.
0000:7D1A BB0007 MOV BX,0700 end de transferência
0000:7D1D B90300 MOV CX,0003 lê 3 setores
LOOP_DE_LEITURA:
Lê os primeiros 3 setores de IO.SYS
(IO.SYS muito mais do que 3 setores).
0000:7D20 50 PUSH AX salva AX
0000:7D21 52 PUSH DX salva DX
0000:7D22 51 PUSH CX salva CX
0000:7D23 E83A00 CALL CONVERT chama rotina de
conversão
0000:7D26 72D8 JB SETUP_TALK salta se houver erro
0000:7D28 B001 MOV AL,01 lê um setor
0000:7D2A E85400 CALL READ_SECTORS lê um setor
0000:7D2D 59 POP CX restaura CX
0000:7D2E 5A POP DX restaura DX
0000:7D2F 58 POP AX restaura AX
0000:7D30 72BB JB TALK salta se erro INT 13
0000:7D32 050100 ADD AX,0001 soma 1 ao end do setor
0000:7D35 83D200 ADC DX,+00 soma 1 ao end do setor
0000:7D38 031E0B7C ADD BX,[7C0B] incrementa o end de mem
com tamanho do setor
0000:7D3C E2E2 LOOP READ_LOOP lê próximo setor
Deixa informação nos registradoresAX, BX, CX
e DX para uso do IO.SYS. Finalmente, salta
para o IO.SYS em 0070:000.
0000:7D3E 8A2E157C MOV CH,[7C15] tipo de mídia
0000:7D42 8A16247C MOV DL,[7C24] número do drive
0000:7D46 8B1E497C MOV BX,[7C49] pega o end inicial do
0000:7D4A A14B7C MOV AX,[7C4B] dir raiz (como LBA)
0000:7D4D EA00007000 JMP 0070:0000 salta para 0070:0000
LOOP_MENSAGEM:
Esta rotina mostra uma mensagem usando a
INT 10, um caracter por vez.
O endereço da mensagem está em DS:SI.
0000:7D52 AC LODSB pega caracter da msg
0000:7D53 0AC0 OR AL,AL fim da mensagem?
0000:7D55 7429 JZ RETURN salta se sim
0000:7D57 B40E MOV AH,0E mostra um caracter
0000:7D59 BB0700 MOV BX,0007 atributos de vídeo
0000:7D5C CD10 INT 10 mostra um caracter
0000:7D5E EBF2 JMP MSG_LOOP faça novamente
CONVERTE:
Esta rotina converte um endereço de setor
(um LBA) num endereço CHS. O LBA está em
DX:AX.
0000:7D60 3B16187C CMP DX,[7C18] parte alta do LBA
maior que sectPerTrk?
0000:7D64 7319 JNB SET_CARRY salta se sim
0000:7D66 F736187C DIV WORD PTR [7C18] divide por
setores por trilha
0000:7D6A FEC2 INC DL soma 1 ao nro de setores
0000:7D6C 88164F7C MOV [7C4F],DL salva número de setores
0000:7D70 33D2 XOR DX,DX zera DX
0000:7D72 F7361A7C DIV WORD PTR [7C1A] div número de cabeças
0000:7D76 8816257C MOV [7C25],DL salva número de cabeças
0000:7D7A A34D7C MOV [7C4D],AX salva nro de cilindros
0000:7D7D F8 CLC limpa carry
0000:7D7E C3 RET retorna
SET_CARRY:
0000:7D7F F9 STC set carry
RETORNA:
0000:7D80 C3 RET retorna
LER_SETORES:
O chamador desta rotina fornece:
AL = número de setores a serem lidos
ES:BX = localização da mem para
transferência e
CHS endereço da leitura a ser transferida
para as localizações de memória 7C25 e
7C4D a 7C4F.
0000:7D81 B402 MOV AH,02 INT 13 lê setores
0000:7D83 8B164D7C MOV DX,[7C4D] pega nro de cilindros
0000:7D87 B106 MOV CL,06 shift contador
0000:7D89 D2E6 SHL DH,CL shift esq. cilindro mais
significativo 6 bits
0000:7D8B 0A364F7C OR DH,[7C4F] OR no número do setor
0000:7D8F 8BCA MOV CX,DX move para CX
0000:7D91 86E9 XCHG CH,CL CH=cilindro baixo,
CL=cilindro alto
+ setor
0000:7D93 8A16247C MOV DL,[7C24] número do drive
0000:7D97 8A36257C MOV DH,[7C25] número da cabeça
0000:7D9B CD13 INT 13 lê setores
0000:7D9D C3 RET retorna
Seguem alguns dados não usados:
0000:7D90 ca86e98a 16247c8a 36257ccd 13c3.... *.....$|.6%|... *


