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

6. O setor de boot

Sab

26

Mai

2007


14:48

(16 votos, média 4.75 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%|...  *

Informações adicionais