Você está na página 1de 14

Trabalho de Microprocessadores: Fazer um simulador do

Neander em C.
1º Passo: Declarar o conjunto de instruções do Neander.
2º Passo: Declarar a memória que tem 256 posições, declarei como
unsigned char pelo fato de já identificar que é complemento de 2.
3º Passo: Declarar as variáveis utilizadas no código.
4º Passo: Fazer função void para cada instrução (LDA, STA, NOP, ...)
de busca e execução.
5º Passo: Fazer DO WHILE para ler a memória, onde se fica
executando os if’s até o momento que o LACO_FINAL for diferente de
1, quando ela for 1 ele sai do DO WHILE.
Código:
// Haydan Miranda Da Conceição
// Microprocessadores
// Simulador Neander in C

#include <stdio.h>
#define STA 16
#define LDA 32
#define ADD 48
#define AND 80
#define NOT 96
#define NOP 00
#define OR 64
#define JZ 160
#define JN 144
#define JMP 128
#define HLT 240
unsigned char memoria_ram [256], ACC=0;
int PC=0, INSTRU=0, ACESSO=0;
int i=0;
int N=0, Z=0;
int LACO_FINAL=0;
int printar=0;

void atualizar_N_Z(void){
if (ACC==0)
Z=1;
else
Z=0;
if(ACC>>7==1) // se pegarmos o '1111 1111' e deslocarmos 7
vezes a direita teremos '0000 0001' onde o último bit de sinal mostra
que é negativo.
N=1;
else
N=0;
return;
}
void funcao_NOP(void){
PC++;
ACESSO++;
INSTRU++;
return;
}
void funcao_STA(int prox_end){ // Parametro para cada função,
quando quiser chamar ela só chamar pelo nome e o argumento será
sibstituido pela nova variavel.
PC=PC+2;
ACESSO= ACESSO+3;
INSTRU++;
memoria_ram[prox_end]=ACC; //STA quer que o
endereço(prox_end) receba o valor do acumulador.
return;
}
void funcao_LDA(int prox_end){
PC=PC+2;
ACESSO=ACESSO+3;
INSTRU++;
ACC=memoria_ram[prox_end];
atualizar_N_Z();
return;
}
void funcao_ADD(int prox_end){
PC=PC+2;
ACESSO=ACESSO+3;
INSTRU++;
ACC=ACC+memoria_ram[prox_end];
atualizar_N_Z();
return;
}
void funcao_OR(int prox_end){
PC=PC+2;
ACESSO=ACESSO+3;
INSTRU++;
ACC=ACC|memoria_ram[prox_end]; // | significa or bit a
bit, não irá pegar o número completo, irá considerar bit a bit de
acordo com a função or.
atualizar_N_Z();
return;
}
void funcao_AND(int prox_end){
PC=PC+2;
ACESSO=ACESSO+3;
INSTRU++;
ACC=ACC & memoria_ram[prox_end]; // & somente um e
comercial pelo fato de ser bit a bit igual o or.
atualizar_N_Z();
return;
}
void funcao_NOT(void){
PC++;
ACESSO++;
INSTRU++;
ACC= ~ACC;
atualizar_N_Z();
return;
}
void funcao_JMP(int prox_end){
PC++;
ACESSO=ACESSO+2;
INSTRU++;
PC=prox_end;
}
void funcao_JZ (int prox_end){
if (ACC==0)
PC=prox_end;
else
PC=PC+2;
ACESSO=ACESSO+2;
INSTRU++;
return;
}
void funcao_JN (int prox_end){
if (ACC>>7==1)
PC=prox_end;
else
PC=PC+2;
ACESSO=ACESSO+2;
INSTRU++;
return;
}
void funcao_HLT (void){
PC++;
ACESSO++;
INSTRU++;
}
int main(void){
for ( i = 0; i < 256; i++) {
memoria_ram[i] = NOP;
}
memoria_ram[0]=LDA;
memoria_ram[1]=10;
memoria_ram[2]=ADD;
memoria_ram[3]=9;
memoria_ram[4]=STA;
memoria_ram[5]=8;
memoria_ram[6]=HLT;
memoria_ram[7]=0;
memoria_ram[8]=0;
memoria_ram[9]=127;
memoria_ram[10]=3;

do {
if (memoria_ram[PC]==NOP){
funcao_NOP();
}
else if(memoria_ram[PC]==STA){
funcao_STA(memoria_ram[PC+1]);
}
else if(memoria_ram[PC]==LDA){
funcao_LDA(memoria_ram[PC+1]);
}
else if(memoria_ram[PC]==ADD){
funcao_ADD(memoria_ram[PC+1]);
}
else if(memoria_ram[PC]==OR){
funcao_OR(memoria_ram[PC+1]);
}
else if(memoria_ram[PC]==AND){
funcao_AND(memoria_ram[PC+1]);
}
else if(memoria_ram[PC]==NOT){
funcao_NOT();
}
else if(memoria_ram[PC]==JMP){
funcao_JMP(memoria_ram[PC+1]);
}
else if(memoria_ram[PC]==JN){
funcao_JN(memoria_ram[PC+1]);
}
else if(memoria_ram[PC]==JZ){
funcao_JZ(memoria_ram[PC+1]);
}
else if(memoria_ram[PC]==HLT){
funcao_HLT();
LACO_FINAL= 1;
}
}
while(LACO_FINAL !=1);

printf("AC = %d\nPC = %d\nAcessos: %d\nInstrucoes =


%d\n\nN = %d\nZ = %d\n",ACC, PC, ACESSO, INSTRU, N, Z);
printf("\n \n tecle:\n (1) para printar a memoria ou (2) finalizar
programa\n");
scanf("%d", &printar);
if (printar==1){
for(i=0; i<256; i++)
printf("%d: %d\n",i,memoria_ram[i]);
}

return 0;
}
Este código que carrega o programa na memória foi utilizado para
quando há o excedente da representatividade do Neander, quando
se soma ou subtrai valores altos, onde se daria overflow, mas como o
Neander não há bit para essa indicação não o representamos em
código.
Eu e alguns colegas implementamos um exercício do computador
Neander função para testar todas as possíveis funções.

Figura 1: Computador Neander.


Linguagem simbólica:
LDA i (1)
JN J> (3)
JZ J> (5)
LDA j (7)
JZ SOMA (9)
NOT (10)
ADD UM (12)
ADD I (14)
STA f (16)
JMP FIM (18)
SOMA ADD i (20)
STA f (22)
JMP FIM (24)
J> LDA j (26)
JN FAZER (28)
OR I (30)
STA f (32)
JMP FIM (34)
FAZER NOP (35)
NOP (36)
NOP (37)
NOP (38)
NOP (39)
AND I (41)
STA f (43)
FIM HLT (44)

i:45=3
j:46=250
f:47=0
UM:48=1

FIM: 44
SOMA:19
J>:25
FAZER:35
Linguagem da máquina:
memoria_ram[0]=LDA;
memoria_ram[1]=45;
memoria_ram[2]=JN;
memoria_ram[3]=25;
memoria_ram[4]=JZ;
memoria_ram[5]=25;
memoria_ram[6]=LDA;
memoria_ram[7]=46;
memoria_ram[8]=JZ;
memoria_ram[9]=19;
memoria_ram[10]=NOT;
memoria_ram[11]=ADD;
memoria_ram[12]=48;
memoria_ram[13]=ADD;
memoria_ram[14]=45;
memoria_ram[15]=STA;
memoria_ram[16]=47;
memoria_ram[17]=JMP;
memoria_ram[18]=44;
memoria_ram[19]=ADD;
memoria_ram[20]=45;
memoria_ram[21]=STA;
memoria_ram[22]=47;
memoria_ram[23]=JMP;
memoria_ram[24]=44;
memoria_ram[25]=LDA;
memoria_ram[26]=46;
memoria_ram[27]=JN;
memoria_ram[28]=35;
memoria_ram[29]=OR;
memoria_ram[30]=45;
memoria_ram[31]=STA;
memoria_ram[32]=47;
memoria_ram[33]=JMP;
memoria_ram[34]=44;
memoria_ram[35]=NOP;
memoria_ram[36]=NOP;
memoria_ram[37]=NOP;
memoria_ram[38]=NOP;
memoria_ram[39]=NOP;
memoria_ram[40]=AND;
memoria_ram[41]=45;
memoria_ram[42]=STA;
memoria_ram[43]=47;
memoria_ram[44]=HLT;
memoria_ram[45]=3;
memoria_ram[46]=250;
memoria_ram[47]=0;
memoria_ram[48]=1;
Colocando esse código que carrega o problema chegamos (i=3 e
j=250) em:

Figura 2: Código feito e simulado.


Agora verificando com o simulador:

Figura 3: Simulador Neander.


Verificados resultados:
Para i=127 e j=0

Figura 4: Código.

Figura 5: Simulador Neander.

Você também pode gostar