Aprendendo Assembly
Doar para o autor
  • Introdução
  • Conteúdo
  • Como usar este livro
  • A base
    • Noção geral da arquitetura
    • Modos de operação
    • Sintaxe
    • Registradores de propósito geral
    • Endereçamento
    • Pilha
    • Saltos
    • Procedimentos
    • Seções e símbolos
    • Instruções assembly x86
    • Instruções do NASM
    • Pré-processador do NASM
    • Syscall no Linux
    • Olá mundo no Linux
    • Revisão
  • Aprofundando em Assembly
    • Registradores de segmento
    • CALL e RET
    • Position-independent executable
    • Atributos
    • Prefixos
    • Flags do processador
    • Instruções condicionais
    • Programando no MS-DOS
    • Interrupções de software e exceções
    • Procedimentos do BIOS
    • Usando instruções da FPU
    • Entendendo SSE
      • Instruções de movimentação de dados
      • Instruções aritméticas
      • Instruções lógicas e de comparação
      • Instruções com inteiros 128-bit
      • Instruções de conversão
  • Programando junto com C
    • Sintaxe do GAS
    • Convenção de chamada da System V ABI
    • Convenções de chamada no Windows
    • Variáveis em C
    • Funções em C
    • Ambiente hosted
    • Ambiente freestanding
    • Inline Assembly no GCC
    • Instruções intrínsecas
  • Depuração de código
    • Entendendo os depuradores
    • Depurando com o GDB
    • Depurando com o Dosbox
  • Apêndices
    • Código de máquina
      • Formato das instruções
      • Atributos e prefixos
      • Immediate
      • Displacement
      • ModR/M e SIB
      • Opcode
      • Prefixo REX
      • Codificação dos registradores
  • Metadados
    • TO DO
    • Referências
Powered by GitBook
On this page
  • Real mode
  • Text mode
  • Executáveis .COM
  • Execução do .COM
  • ORG | Origin
  • Hello World no MS-DOS

Was this helpful?

Export as PDF
  1. Aprofundando em Assembly

Programando no MS-DOS

Conhecendo o ambiente do MS-DOS.

PreviousInstruções condicionaisNextInterrupções de software e exceções

Last updated 3 years ago

Was this helpful?

O clássico MS-DOS, antigo sistema operacional de 16 bits da Microsoft, foi muito utilizado e até hoje existem projetos relacionados a esse sistema. Existe por exemplo o que é um sistema operacional de código aberto e que é compatível com o MS-DOS.

A famosa "telinha preta" do Windows, o prompt de comando, muitas vezes é erroneamente chamado de MS-DOS devido aos dois usarem o mesmo shellscript chamado de Batch. Isso fazia com que comandos rodados no MS-DOS fossem quase totalmente compatíveis na linha de comando do Windows.

Mas o prompt de comandos do Windows não é o MS-DOS. Esse é apenas o Terminal do sistema operacional Windows e que usa uma versão mais avançada do mesmo shellscript que rodava no MS-DOS.

Real mode

O MS-DOS era um sistema operacional que rodava em modo de processamento real mode, o famoso modo de 16-bit que é compatível com o 8086 original.

Text mode

Existem modos diferentes de se usar a saída de vídeo, isto é, o monitor do computador. Dentre os vários modos que o monitor suporta, existe a divisão entre modo de texto (text mode) e modo de vídeo (video mode).

O modo de vídeo é este modo que o seu sistema operacional está rodando agora. Nele o software define informações de cor para cada pixel da tela, formando assim imagens desde mais simples (formas opacas) até as mais complexas (imagens renderizadas tridimensionalmente). Todas essas imagens que você vê são geradas pixel a pixel para serem apresentadas pelo monitor.

Já o MS-DOS rodava em modo de texto, cujo este modo é bem mais simples. Ao invés de você definir cada pixel que o monitor apresenta, você define unicamente informações de caracteres. Imagine por exemplo que seu monitor seja dividido em grade formando 80x25 quadrados na tela. Ou seja, 80 colunas e 25 linhas. Ao invés de definir cada pixel você apenas definia qual caractere seria apresentado naquele quadrado e um atributo para esse caractere.

Executáveis .COM

O formato de executável mais básico que o MS-DOS suportava era os de extensão .com que era um raw binary. Esse termo é usado para se referir a um "binário puro", isto é, um arquivo binário que não tem qualquer tipo de formatação especial.

Uma comparação com arquivos de texto seria você comparar um código fonte em C com um arquivo de texto "normal". O código fonte em C também é um arquivo de texto, porém ele tem formatações especiais que seguem a sintaxe da linguagem de programação. Enquanto o arquivo de texto "normal" é apenas texto, sem seguir qualquer regra de formatação.

No caso do raw binary é a mesma coisa, informação binária sem qualquer regra de formatação especial. Este executável do MS-DOS tinha como "entry point" logo o primeiro byte do arquivo. Como eu já disse, não tinha qualquer regra especial nele então você poderia organizá-lo da maneira que quisesse manualmente.

Execução do .COM

O processo que o MS-DOS fazia para executar esse tipo de executável era tão simples quanto possível. Seguindo o fluxo:

  • Recebe um comando na linha de comando.

  • Coloca o tamanho em bytes dos argumentos passados pela linha de comando no offset 0x80 do segmento do executável.

  • Coloca os argumentos da linha de comando no offset 0x81 como texto puro, sem qualquer formatação.

  • Carrega todo o .COM no offset 0x100

  • Define os registradores DS, SS e ES para o segmento onde o executável foi carregado.

  • Faz um call no endereço onde o executável foi carregado.

Perceba que a chamada do executável nada mais é que um call, por isso esses executáveis finalizavam simplesmente executando um ret. Mais simples impossível, né?

ORG | Origin

org endereço_inicial

A essa altura você já deve ter reparado que o NASM calcula o endereço dos rótulos sozinho sem precisar da nossa ajuda, né? Então, mas ele faz isso considerando que o primeiro byte do nosso arquivo binário esteja especificamente no offset 0. Ou seja, ele começa a contar do zero em diante. No caso de um executável .COM ele é carregado no offset 0x100 e não em 0, então o cálculo vai dar errado.

Mas o NASM contém a diretiva org que serve para dizer para o NASM a partir de qual endereço ele deve calcular o endereço dos rótulos, ou seja, o endereço de origem do nosso binário. Veja o exemplo:

bits 16
org 0x100

msg: db "abc"

codigo:
  mov ax, 77
  ret

O rótulo codigo ao invés de ter o endereço calculado como 0x0003 como normalmente teria, terá o endereço 0x0103 devido ao uso da diretiva org na segunda linha.

Hello World no MS-DOS

Um pequeno exemplo de "Hello World" (ou "Hi") para o MS-DOS:

hello.asm
bits 16
org 0x100

mov ah, 0x0E
mov al, 'H'
int 0x10

mov al, 'i'
int 0x10

ret

Experimente compilar como um raw binary com extensão .com e depois executar no Dosbox (ou FreeDOS ou qualquer projeto semelhante).

$ nasm hello.asm -o hello.com

A instrução INT e o que está acontecendo aí será explicado nos dois tópicos posteriores a esse.

FreeDOS