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: 16722
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%|... *