SISTEMAS OPERACIONAIS I  -  1998/2  -  TRABALHO PRÁTICO
MÁXIMO DE 3 ALUNOS POR GRUPO  -  DATA PARA ENTREGA = 24/FEV/1999

O trabalho consiste em implementar um montador para o processador cuja arquitetura está
descrita abaixo. Deve ser utilizada a linguagem C, C++ ou Java.

O montador recebe como entrada um arquivo texto (ASCII) comum. Este arquivo texto não
possui qualquer marca de formatação. São apenas linhas separadas por CR e/ou LF. Espaços e/ou
tabulações separam os elementos de uma linha. O montador gera como saída um arquivo objeto,
cujo formato (estrutura interna) é descrito mais adiante.

A entrega consiste no seguinte:
- Listagem do código fonte;
- Demonstração no computador, com a presença de todos os integrantes do grupo, em horário a ser
combinado. Serão feitas perguntas sobre o trabalho e somente será atribuída nota aos componentes
do grupo que participarem da demonstração.

Características da Linguagem de Montagem a ser implementada

1. Formato do código fonte
<rótulo>:          <operação>       <operando>         ; <comentário>

2. Diretivas suportadas
<rótulo>:          SPACE             <número de bytes>
Reserva o número especificado de bytes na memória, sem inicializar.

<rótulo>:          CONST             <conteúdo inicial>
Reserva um byte de memória e inicializa.

<rótulo>:          EXTERN
Define um símbolo externo.

                       PUBLIC             <rótulo>
Declara um símbolo como público.

3. Conjunto de instruções do processador
 
BRK                   Para o processador           00H
LDI end16             ACC:=valor16                 99H valor-lsb valor-msb
LDA end16             ACC:=[end16]                 ADH end-lsb end-msb
STA end16             [end16]:=ACC                 8DH end-lsb end-msb
INC end16             [end16]:=[end16]+1           EEH end-lsb end-msb
DEC end16             [end16]:=[end16]-1           CEH end-lsb end-msb
ADC end16             ACC:=ACC+[end16]+Cy          6DH end-lsb end-msb
SBC end16             ACC:=ACC-[end16]             EDH end-lsb end-msb
BCC desl8             Se Cy=0 então PC*PC+desl8    90H desl
BCS desl8             Se Cy=1 então PC*PC+desl8    B0H desl
BEQ desl8             Se Zr=1 então PC*PC+desl8    F0H desl
BNE desl8             Se Zr=0 então PC*PC+desl8    D0H desl
JMP end16             PC:=end16                    4CH end-lsb end-msb
CLC                   Cy:=0                        18H
 
4. Lista obrigatória de erros, mas que pode ser expandida
- Símbolo indefinido;     - Símbolo duplamente definido;
- Operação não identificada;    - Número errado de operandos;
- Posição alvo fora do alcançe;   - Símbolo externo exportado;
- Símbolo externo usado em salto condicional.

5. Formato do arquivo objeto gerado
O arquivo objeto gerado deverá conter, além do código objeto, um mapa de bits para
relocação, uma tabela de uso e uma tabela de definições. O formato do arquivo é mostrado abaixo,
onde int representa um inteiro com 32 bits.

int assinatura = 0x12345678;
int tamanho_do_cabeçalho_em_bytes = 24;
int tamanho_do_código_gerado_em_bytes;
int tamanho_do_mapa_de_relocação_em_bytes;
int tamanho_da_tabela_de_uso_em_entradas;
int tamanho_da_tabela_de_definição_em_entradas;

char código_gerado [ tamanho_do_código_gerado_em_bytes ];

char mapa_de_relocação [ tamanho_do_mapa_de_relocação_em_bytes ];

struct {
 char símbolo[32];
 int endereço_de_uso;
 char sinal_adição_ou_subtração;
 } tabela_de_uso[ tamanho_da_tabela_de_uso_em_entradas ];

struct {
 char símbolo[32];
 int valor_do_símbolo;
 int absoluto_0_ou_relativo_1;
 } tabela_de_definição[ tamanho_da_tabela_de_definição_em_entradas ];
 

6. Observações
- A tabela de símbolos do montador deve ser implementada com cálculo de endereço (função hash).
- O mapa de relocação deve usar o bit 1 para relativo e o bit 0 para absoluto.
- Todos os valores relativos são endereços que ocupam 2 bytes e devem ser tratados como tal.
- Dentro do mapa de relocação, bit mais significativo dentro de um mesmo byte significa byte
anterior no código executável.
- O tamanho do mapa de relocação é dado pelo tamanho do código gerado em bytes dividido por 8.
Caso não resulte em número inteiro de bytes, completar com zeros até que o mapa de bits tenha um
tamanho múltiplo de 8.