Simulação da CPU
Este projeto é simular um sistema de computador simples que consiste em uma CPU e memória. A CPU e a memória são simuladas por processos separados que se comunicam. A memória contém um programa que a CPU executará e, em seguida, a simulação terminará.
Para CPU:
- Ele terá estes registros: PC, SP, IR, AC, X, Y.
- Ele apoiará as instruções mostradas abaixo.
- Ele executará o programa de usuário no endereço 0.
- As instruções são buscadas no IR da memória. O operando pode ser buscado em uma variável local.
- Cada instrução deve ser executada antes que a próxima instrução seja buscada.
- A pilha de usuários reside no final da memória do usuário e cresce em direção ao endereço 0.
- A pilha do sistema reside no final da memória do sistema e cresce em direção ao endereço 0.
- Não há aplicação de hardware do tamanho da pilha.
- O programa termina quando a instrução final é executada. Os 2 processos devem terminar naquele momento.
- O programa do usuário não pode acessar a memória do sistema (saídas com a mensagem de erro).
Para memória:
- Ele consistirá em entradas inteiras de 2000, 0-999 para o programa de usuário, 1000-1999 para o código do sistema.
- Ele apoiará duas operações: Leia (endereço) - retorna o valor no endereço; Write (endereço, dados) - grava os dados no endereço
- A memória se inicializará lendo um arquivo de programa.
Para o cronômetro:
- Um cronômetro interromperá o processador após cada instruções X, onde x é um parâmetro de linha de comando.
Para processamento de interrupção:
- Existem duas formas de interrupções: o timer e uma chamada do sistema usando a instrução int.
- Nos dois casos, a CPU deve entrar no modo kernel.
- O ponteiro da pilha deve ser alterado para a pilha do sistema.
- Os registros de SP e PC devem ser salvos na pilha do sistema. (O manipulador pode salvar registros adicionais).
- Uma interrupção do timer deve causar execução no endereço 1000.
- A instrução int deve causar execução no endereço 1500.
- As interrupções devem ser desativadas durante o processamento de interrupções para evitar a execução aninhada.
- A instrução IRET retorna de uma interrupção.
Conjunto de instruções:
-> 1 = Valor da carga # Carregue o valor no CA
-> 2 = Carregar addr # Carregar o valor no endereço no AC
-> 3 = loadind addr # carregue o valor do endereço encontrado no endereço fornecido no CA. (Por exemplo, se o loadind 500 e 500 contiverem 100, então carregue de 100).
-> 4 = loadIdxx addr # carregue o valor em (endereço+x) no AC. (Por exemplo, se LoadIdxx 500 e X contiver 10, então carregue de 510).
-> 5 = loadIdxy addr # carregue o valor em (endereço+y) no AC
-> 6 = LoadSpx # Carga de (sp+x) no CA (se SP for 990 e x é 1, carregar de 991).
-> 7 = armazenar addr # Armazene o valor no CA no endereço
-> 8 = Get # recebe um INT aleatório de 1 a 100 no AC
-> 9 = Coloque a porta # se porta = 1, grava AC como um int na tela; Se porta = 2, grava CA como um char na tela
-> 10 = addx # Adicione o valor em x ao AC
-> 11 = Addy # Adicione o valor em y ao AC
-> 12 = subx # subtraia o valor em x do AC
-> 13 = suby # subtraia o valor em y do AC
-> 14 = copytox # copie o valor no AC para x
-> 15 = copyfromx # copie o valor em x para o AC
-> 16 = copytoy # copie o valor no AC para y
-> 17 = copyfromy # copie o valor em y para o AC
-> 18 = copytososp # copie o valor no AC para o SP
-> 19 = copyfromp # copie o valor em SP para o AC
-> 20 = Jump addr # salto para o endereço
-> 21 = Jumpifequal addr # salto apenas para o endereço se o valor no AC for zero
-> 22 = JumpIfnotequal addr # salto apenas para o endereço se o valor no CA não for zero
-> 23 = Ligue para addr # push Return endereço na pilha, pule para o endereço
-> 24 = RET # Endereço de retorno pop da pilha, pule para o endereço
-> 25 = incx # incremento o valor em x
-> 26 = DECX # diminui o valor em x
-> 27 = push # push ac na pilha
-> 28 = pop # pop da pilha para AC
-> 29 = int # Execute a chamada do sistema
-> 30 = IRET # Retorno da chamada do sistema
-> 50 = Execução final #
====================================================================================
A pasta de amostra contém 5 arquivos de amostra.
Sample1.txt
- Testes as instruções de carga indexada.
- Imprime duas tabelas, uma de AZ, a outra de 1-10.
Sample2.txt
- Testes as instruções de chamada/ret.
- Imprime um rosto onde as linhas são impressas usando chamadas de sub -rotina.
sample3.txt
- Testes as instruções INT/IRET.
- O loop principal é imprimir a letra A seguida por um número que está sendo incrementado periodicamente pelo temporizador.
- O número aumentará mais rapidamente se o período do timer for mais curto.
Sample4.txt
- Testes a operação adequada da pilha de usuários e da pilha do sistema e também testa que o acesso à memória do sistema no modo de usuário fornece um erro e sai.
sample5.txt
- Este é um que você deve criar. Certifique -se de incluir comentários para que a série saiba o que o programa está fazendo.
====================================================================================
Etapa para compilar e executar o projeto:
- S1: copie os arquivos de origem no sistema Linux.
- S2: Altere os arquivos diretos para origem
- S3: Execute o seguinte comando: gcc memória.c cpu.c simulator.c
- S4: Execute o programa: ./a.out
- S5: De acordo com as informações de saída, insira o parâmetro X, o nome do arquivo que você deseja executar respectivamente. Cada item termina com "Enter". por exemplo: 10 ( n) sample2.txt
- S6: Repita S4 para os restantes arquivos de teste de amostra para obter as várias saídas