Skip to content

cgcannismajoris/AssemblerM

Repository files navigation

AssemblerM

Um montador para o Assembly M.

##O que ele faz? Realiza a montagem, a partir de um arquivo de texto de entrada, de um arquivo binário que estará no formato compatível do processador conceitual CPUM.

##Requisitos recomendados

  • Sistema Operacional Unix-like ou GNU/Linux mais recente;
  • GCC 4.9.1 ou superior;
  • GNU Make 4.0 ou superior.

Requisito opcional

  • Qt Creator 5.3.0 ou superior.

##Estrutura do projeto

A seguir, está disposto a organização básica do projeto AssemblerM.

/AssemblerM					: pasta-pai do projeto	
	/data					: arquivos de entrada/saída e relativos ao projeto
	/src					: pasta de códigos-fonte
	/tools					: pasta de ferramentas
	.gitignore				: arquivo gitignore
	AssemblerM.pro			: árvore do projeto (Qt Creator)
	AssemblerM.pro.user		: estruturação do projeto (Qt Creator)
	COPYING3				: arquivo de licença
	Diagrama - Montador.png	: diagrama de classes (adaptado) do projeto
	Makefile				: arquivo Makefile
	README.md				: arquivo LEIA-ME

Obs.: como cortesia da casa, é oferecido um layout simples do projeto para o Qt Creator.

##Procedimento de compilação do AssemblerM Estando-se na pasta pai do projeto ("/AssemblerM"), realize o comando abaixo:

$ make

##Procedimentos de utilização via Terminal Através de um terminal de comando do Linux, observa-se o formato de entrada abaixo:

$ ./bin/AssemblerM <ARQUIVO_ENTRADA> <ARQUIVO_SAÍDA> <ARQUIVO_DICIONARIO> <arg1> <arg2> ... <argn>

Descrição dos argumentos:

<ARQUIVO_ENTRADA>        : é um arquivo de texto codificado no padrão ANSI ASCII contendo o 
	                       código a ser montado.
<ARQUIVO_SAÍDA>          : é o arquivo de saída do processo de montagem seguido.
<ARQUIVO_DICIONARIO>     : é o arquivo de dicionário a ser utilizado na montagem.
<arg1> <arg2> ... <argn> : os valores numéricos inteiros para configurar os valores iniciais
                           dos registradores de entrada declarados no cabeçalho do arquivo de
                           texto de entrada.

A chamada do programa sem argumentos resultará na exibição de uma descrição simplificada da lista de argumentos.

Se a execução for bem-sucedida, então será gerado o arquivo binário para a CPUM.

##Sintaxe da linguagem M A sintaxe da linguagem é semelhante às linguagens conceituais monolíticas.

###Sintaxe do Cabeçalho Todo código-fonte deve ter, em seu cabeçalho (primeira linha), a declaração da máquina a ser utilizada.

<NOME_DA_MÁQUINA>:<OUTREG_1>,<OUTREG_2>,...,<OUTREG_N><-<INREG_1>,<INREG_2>,...,<INREG_N>

Significado:

<NOME_DA_MÁQUINA>                    : é o nome da máquina;
<OUTREG_1>,<OUTREG_2>,...,<OUTREG_N> : é a declaração dos registradores de saída;
<-                                   : seta que determina o significado dos registradores 
									   (será tratada a seguir);
<INREG_1>,<INREG_2>,...,<INREG_N>    : é a declaração dos registradores de entrada. É 
								       esta lista de registradores que receberá os valores numéricos
								       inteiros de entrada descritos anteriormente;

A seta descrita acima (<-), pode ser invertida, ou seja, escrita como "->". Todavia, a ordem dos registradores também deverá ser alterada, isto é:

<NOME_DA_MÁQUINA>:<INREG_1>,<INREG_2>,...,<INREG_N>-><OUTREG_1>,<OUTREG_2>,...,<OUTREG_N>

Em resumo, a seta indica o sentido do fluxo do processamento descrito nas linhas subsequentes. Tal fluxo pode ser dar como:

1. Os registradores de entrada recebem os dados de entrada;
2. Os dados armazenados são processados seguindo a lógica descrita nas linhas subsequentes 
   ao cabeçalho;
3. Os registradores de saída armazenam os resultados do processamento.

É importante ressaltar que o resultado do processamento só será armazenado nos registradores de saída, caso a lógica descrita no código viabilize este transporte. A utilização de todos os registradores declarados fica a cargo do usuário, mas a tentativa de uso de registradores não declarados gera erro de montagem do programa.

###Sintaxe das Instruções Toda instrução deve possuir um rótulo, um identificador de operação/teste, um registrador a ser utilizado e o(s) endereço(s) da próxima instrução.

Existem duas operações e um teste. São eles:

  • INC : incrementa um determinado registrador em uma unidade;
  • DEC : decrementa um determinado registrador em uma unidade;
  • ZERO : testa se um registrador é igual a 0.

As instruções de operação seguem as seguintes sintaxes:

1. <RÓTULO>: faca <OPERACAO> <REGISTRADOR> va_para <RÓTULO_DESTINO>
2. <RÓTULO>: <OPERACAO> <REGISTRADOR> <RÓTULO_DESTINO>

Para ambos os casos, seguem os seguintes significados:

<RÓTULO>         : Rótulo da instrução;
<OPERACAO>       : Operação a ser realizada (INC ou DEC);
<REGISTRADOR>    : Registrador a ser utilizado na operação;
<RÓTULO_DESTINO> : Rótulo da próxima instrução.

A instrução de teste pode seguir uma das possibilidades:

1. <RÓTULO>: se zero <REGISTRADOR> entao <RÓTULO_DESTINO_VERDADE> senao <RÓTULO_DESTINO_FALSO>
2. <RÓTULO>: faca zero <REGISTRADOR> va_para <RÓTULO_DESTINO_VERDADE> <RÓTULO_DESTINO_FALSO>
3. <RÓTULO>: zero <REGISTRADOR> <RÓTULO_DESTINO_VERDADE> <RÓTULO_DESTINO_FALSO>

Para todos os casos, há os seguintes significados:

<RÓTULO>                 : Rótulo da instrução;
<REGISTRADOR>            : Registrador a ter seu valor verificado;
<RÓTULO_DESTINO_VERDADE> : Rótulo da próxima instrução caso o teste retornar verdade.
<RÓTULO_DESTINO_FALSO>   : Rótulo da próxima instrução caso o teste retornar falso.

A linguagem é case sensitive ("sensível ao caso").

####Determinando o fim do programa

O fim do programa pode ser determinado referenciando um rótulo inexistente no rótulo de destino da instrução.

###Exemplo de Código

O código a seguir transfere o valor contido no registrador b para o registrador a, para valores maiores do que 0.

M:a<-b
r1: faca inc a va_para r2
r2: faca dec b va_para r3
r3: se zero b entao r5 senao r1

Atenta-se ao fato de que existe mais de uma possibilidade de escrita das instruções. O código a seguir é equivalente ao anterior:

M:a<-b
r1: inc a r2
r2: dec b r3
r3: zero b r5 r1

Uma observação importante, é que o rótulo "r5", referenciado na instrução rotulada "r3", não existe. Logo, se o teste "zero b" resultar em verdade, o programa será finalizado. Como boa prática de programação, recomenda-se seguir um único padrão de escrita, visando uma maior facilidade de entendimento humano do código.

###Comentários É possível fazer comentários no código, desde que seja atendida a seguinte condição:

  • O comentário deve OBRIGATORIAMENTE vir depois de uma instrução;

Para fazer um comentário, deve-se iniciar a escrita com ";" ou "#".

Exemplo de código comentado:

M:a<-b
r1: faca inc a va_para r2	; Incrementa o registrador a e vai para r2
r2: faca dec b va_para r3	; Decrementa o registrador b e vai para r3
r3: se zero b entao r5 senao r1 ; Se b for zero, então finaliza. Caso contrário, volta para r1

##Arquivo de Saída (Função Computada) O arquivo de saída é função computada do programa. Cada linha do arquivo conterá a configuração:

(<NÚMERO_DA_PRÓXIMA_INSTRUÇÃO>, (<VALOR_REG1>, <VALOR_REG2>, ..., <VALOR_REG_N>))

A ordem dos registradores é a mesma ordem da declaração da máquina realizada no código.

##Exemplo de Execução

Considere o código abaixo:

M:a<-b
r1: faca inc a va_para r2
r2: faca dec b va_para r3
r3: se zero b entao r5 senao r1

Se executarmos o código acima com a seguinte linha comando:

./MachineM codigo.txt funcaoComputada.txt 3

O arquivo funcaoComputada.txt conterá:

(1, (0, 3))
(2, (1, 3))
(3, (1, 2))
(1, (1, 2))
(2, (2, 2))
(3, (2, 1))
(1, (2, 1))
(2, (3, 1))
(3, (3, 0))
(4, (3, 0))

##Diagrama do Projeto Abaixo é mostrado o diagrama de classes (adaptado) do projeto.

![alt text][Diagrama] [Diagrama]:https://github.com/cgcannismajoris/AssemblerM/blob/alternative/Diagrama%20-%20Montador.png?raw=true "Diagrama"

##Licença O AssemblerM é amparado pela licença GNU General Public License V3.0.

##Autores Cristan Costa Mello - cristianc.mello@gmail.com
Gustavo Freitas de Amorim - gustavofreitasamorim@gmail.com