Nesta seção serão apresentados os avisos importantes referentes ao trabalho 1.
Um montador (assembler) é uma ferramenta que converte código em linguagem de montagem (assembly) para código em linguagem de máquina. Neste trabalho, você irá implementar um montador para a linguagem de montagem do computador IAS, que produza como resultado um mapa de memória para ser utilizado no simulador do IAS, que pode ser encontrado em: http://www.ic.unicamp.br/~edson/disciplinas/mc404/2016-2s/abef/IAS-sim/index.html.
Nesta seção serão apresentadas as especificações gerais do montador, da linguagem de montagem aceita por ele e da linguagem de máquina que o montador deve produzir.
O arquivo de saída do montador é um mapa de memória que contém linhas no formato:
AAA DD DDD DD DDD
Na linha acima, AAA é uma sequência de 3 dígitos hexadecimais que representa o endereço de memória, totalizando 12 bits. Já DD DDD DD DDD é uma sequência de 10 dígitos hexadecimais, que totaliza 40 bits e representa um dado ou duas instruções do IAS, conforme já visto em aula. Note que existem caracteres de espaço na linha, num total de exatos 4 espaços - é importante que seu montador produza um mapa de memória EXATAMENTE nesse formato para permitir a execução dos casos de teste. Não deve haver caracteres extras ou linhas em branco, apenas linhas no formato acima.
O arquivo de entrada do montador deve ser um arquivo de texto tal que cada linha deve ser como uma das seguintes:
[rotulo:] [instrucao] [# comentario]ou
[rotulo:] [diretiva] [# comentario]
Nas linhas acima, os colchetes determinam elementos opcionais - ou seja, qualquer coisa é opcional, podendo então haver linhas em branco no arquivo de entrada, ou apenas linhas de comentário, ou linhas só com uma instrução, etc. É possível que haja múltiplos espaços em branco no início ou fim da linha ou entre os elementos. Como exemplo, as seguintes linhas são válidas num arquivo de entrada para o montador:
vetor1: vetor2: .word 10 vetor3: .word 10 # Comentario apos diretiva .word 10 .word 10 # Comentario apos diretiva # Comentario sozinho vetor4: ADD "0x0000000100" vetor5: ADD "0x0000000100" # Comentario apos instrucao ADD "0x0000000100"e as seguintes linhas são inválidas:
rotulo1: outro_rotulo: mais_um_rotulo: vetor: .word 10 ADD "0x000000000100" .word 10 .align 5 vetor: ADD "0x000000000100" .word 10 ADD "0x000000000100" ADD "0x000000000100"
Algumas regras gerais do montador:
./ias-as entrada.s saida.mapque lê um arquivo denominado entrada.s e gera o mapa de memória no arquivo saida.map, e
./ias-as prog.sque lê um arquivo de nome prog.s e imprime o mapa de memória na saída padrão. Você não deve supor que os nomes dos arquivos tenham sufixos pré-determinados, como ".s", ".asm", ".map", etc. Dessa forma, os seguintes comandos também devem ser válidos:
./ias-as arq.asm arq.hex ./ias-as arq.txt arq.out
As próximas seções descrevem as regras referentes à linguagem de montagem.
Comentários são cadeias de caracteres que servem para documentar ou anotar o código. Essas cadeias devem ser desprezadas durante a montagem do programa. Todo texto à direita de um caractere "#" (cerquilha) é considerado comentário.
Rótulos são compostos por caracteres alfanuméricos e podem conter o caractere "_" (underscore). Um rótulo é definido como uma cadeia de caracteres que deve ser terminada com o caractere ":" (dois pontos) e não pode ser iniciada com um número. Exemplos de rótulos válidos são:
varX: var1: _varX2: laco_1: __DEBUG__:Exemplos de rótulos inválidos são:
varx:: :var1 1var: laco ro:tulo
Todas as diretivas da linguagem de montagem do IAS começam com o caractere "." (ponto). As diretivas podem ter um ou dois argumentos - tais argumentos podem ser dos seguintes tipos:
| HEX | um valor na representação hexadecimal. Estes valores possuem exatamente 12 dígitos, sendo os dois primeiros '0' e 'x' e os 10 últimos dígitos hexadecimais, ou seja, 0-9, a-f ou A-F. Ex: 0x0a0Ef217D0 |
| DEC(min:max) | valores numéricos na representação decimal. Apenas valores no intervalo (min:max) são válidos e seu montador deve realizar esta verificação. Caso o valor não esteja no intervalo (min:max), o montador deve emitir uma mensagem de erro na saída de erro e interromper o processo de montagem sem produzir o mapa de memória na saída padrão (stdout) ou no arquivo de saída. |
| ROT | caracteres alfanuméricos e "_" (underscore). Não pode começar com número (veja a descrição de rótulos acima) e deve terminar com ':'. |
| SYM | caracteres alfanuméricos e "_" (underscore) - não pode começar com número. |
A Tabela 1, abaixo, apresenta a sintaxe das diretivas de montagem e os tipos de seus argumentos.
| Sintaxe | Argumento 1 | Argumento 2 |
| .set | SYM | HEX | DEC(0:231-1) |
| .org | HEX | DEC(0:1023) | |
| .align | DEC(1:1023) | |
| .wfill | DEC(1:1023) | HEX | DEC(-231:231-1) | ROT | SYM |
| .word | HEX | DEC(0:232-1) | ROT | SYM |
O caractere "|" separa as opções. Por exemplo: a diretiva .org pode receber como argumento um valor hexadecimal (HEX) ou decimal no intervalo (0:1023). Dessa forma, as linhas do seguinte programa são válidas:
.org 0x0000000000 .org 0x000000000f .org 100enquanto que as seguintes linhas são inválidas
.org 0x0000000000 | 10 .org -10 .org 0x000 20 .org
A descrição do comportamento de cada uma das diretivas está na apostila de programação do computador IAS (programando_o_IAS.pdf). Também podem ser encontradas nos slides das aulas.
As instruções que requerem um endereço podem ser descritas utilizando-se qualquer um dos seguintes formatos:
Note que no segundo campo é possível usar um endereço em hexadecimal (HEX) ou decimal (DEC), ou o identificador de um rótulo (sem o caractere ':'). O endereço, ou o rótulo, deve ser descrito entre aspas duplas. Exemplos válidos são:
ADD "laco" SUB "0x00000000F4"
Algumas instruções não requerem o campo endereço (RSH, por exemplo). Se o programa especificar o campo endereço para estas instruções, seu montador deve emitir uma mensagem de erro e interromper a montagem. Para as instruções que não requerem o campo endereço seu montador deve preencher os bits referentes ao campo endereço no mapa de memória com zeros.
A Tabela 2, abaixo, apresenta os mnemônicos válidos e as instruções que devem ser emitidas para cada um dos casos.
| Mnemônico | Instrução a ser emitida |
| LD | LOAD M(X) |
| LD- | LOAD -M(X) |
| LD| | LOAD |M(X)| |
| LDmq | LOAD MQ |
| LDmq_mx | LOAD MQ,M(X) |
| ST | STOR M(X) |
| JMP | JUMP M(X,0:19) se o alvo for uma instrução à esquerda da palavra de memória (endereços do tipo HEX ou DEC sempre indicam endereços à esquerda enquanto que rótulos podem indicar endereços à esquerda ou direita). |
| JUMP M(X,20:39) se o alvo for uma instrução à direita de uma palavra de memória. | |
| JUMP+ | JUMP+M(X,0:19) se o alvo for uma instrução à esquerda da palavra de memória (endereços do tipo HEX ou DEC sempre indicam endereços à esquerda enquanto que rótulos podem indicar endereços à esquerda ou direita). |
| JUMP+M(X,20:39) se o alvo for uma instrução à direita de uma palavra de memória. | |
| ADD | ADD M(X) |
| ADD| | ADD |M(X)| |
| SUB | SUB M(X) |
| SUB| | SUB |M(X)| |
| MUL | MUL M(X) |
| DIV | DIV M(X) |
| LSH | LSH |
| RSH | RSH |
| STaddr | STOR M(X,8:19) se X for o endereço de uma instrução à esquerda de uma palavra. |
| STOR M(X,28:39) se X for o endereço de uma instrução à direita de uma palavra. |
Seu montador deve tratar erros. Sempre que houver um erro, seu montador deve emitir uma mensagem de erro no arquivo de saída e terminar a execução sem produzir o mapa de memória, ou seja, sem escrever o mapa de memória no arquivo de saída. Caso o arquivo de saída não tenha sido fornecido, a mensagem de erro dever ser emitida na saída padrão e o mapa de memória não deve ser escrito na saída padrão.
As mensagens de erro devem seguir o seguinte padrão:
ERROR on line XX mensagem!onde XX é o número da linha do arquivo de entrada que causou o erro e "mensagem" é a mensagem de erro. Esta mensagem deve estar na linha subsequente à primeira. Exemplos:
ERROR on line 3 addu is not a valid mnemonic!
ERROR on line 56 0x00$02 is not a valid hex number!