1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
using namespace std;
string ConverteDecimal (unsigned int val);
unsigned int ConverteBinarioUnsigned(string s);
int ConverteBinarioSigned(string s);
void IniciaVetores(vector<string>* vetor, int k);
void InterpretaLinha(string linha, vector<string>* registradores, vector<string>* mem);
int main()
{
// registradores guarda AC, BC, CC e IC respectivamente.
// mem guarda os 128 espaços de memória disponíveis no ph2.
vector<string> registradores, mem;
IniciaVetores(®istradores, 4); // inicia o vetor com valores zerados.
IniciaVetores(&mem, 256); // inicia o vetor com valores zerados.
while (true)
{
string linha; // linha de comando a ser inserida. Ex.: AC=00000001
getline (cin, linha);
InterpretaLinha(linha, ®istradores, &mem);
if (linha.substr(0, 3)=="LDR") break;
}
cout << "AC=" << registradores[0] << endl;
cout << "BC=" << registradores[1] << endl;
cout << "CC=" << registradores[2] << endl;
cout << "IC=" << registradores[3] << endl;
}
string ConverteDecimal(unsigned int val) // função que converte um valor inteiro decimal para binário.
{
string str="";
unsigned int mask = 1;
for (int i=0; i<8; i++)
{
((val&mask)==0) ? str='0'+str : str='1'+str; // AND bit a bit entre val e mask.
mask <<=1; // move os bits de mask 1 bit para a direita.
}
return str;
}
unsigned int ConverteBinarioUnsigned(string str)
{
unsigned int valor=0;
for (int i=0; i<8; i++)
{
if (str[7-i] == '1') valor+=1<<i; // do fim pro início da string, vem testando se o bit é 0 ou 1
}
return valor;
}
int ConverteBinarioSigned(string str)
{
int valor=0;
if (str[0]=='1') // COMPLEMENTO DE 2
{
for (int i=0; i<8; i++)
{
(str[7-i]=='1') ? str[7-i]='0' : str[7-i]='1'; // inverte os bits
if (str[7-i]=='1') valor+=1<<i;
}
valor++; // adiciona 1
return (-valor);
}
// se for positivo, chama ConverteBinarioUnsigned
return (ConverteBinarioUnsigned(str));
}
void IniciaVetores(vector<string>* vetor, int k)
{
for (int i=0; i<k; i++)
vetor->push_back("00000000");
}
void InterpretaLinha(string linha, vector<string>* registradores, vector<string>* mem)
{
// posicao é a variável que vai guardar a posição do caractere '=', se achar.
size_t posicao;
posicao = linha.find("=");
// npos é uma constante que significa (entre outros) o fim da string.
// se achou '=' quer dizer que está atualizando algo. Caso contrário, é LDR.
if (posicao!=string::npos)
{
string atualizado; // representa o que vai ser atualizado: registrador ou memoria.
atualizado = linha.substr(0, posicao); // pega a posição do início da string até '='
// Aqui, os if's acham o registrador a ser atualizado. Após isso, a variável 'atualizado'
// recebe a substring de linha que contém o valor que vai substituir o antigo valor.
// Caso seja a memória atualizada, e não um registrador, atualizado recebe receberá o end
// de memória a ser atualizado.
if (atualizado=="AC")
{
atualizado = linha.substr(posicao+1); // 'posicao'+1 = caracter logo após '='.
registradores->at(0) = atualizado;
return;
}
if (atualizado=="BC")
{
atualizado = linha.substr(posicao+1); // 'posicao'+1 = caracter logo após '='.
registradores->at(1) = atualizado;
return;
}
if (atualizado=="CC")
{
atualizado = linha.substr(posicao+1); // 'posicao'+1 = caracter logo após '='.
registradores->at(2) = atualizado;
return;
}
if (atualizado=="IC")
{
atualizado = linha.substr(posicao+1); // 'posicao'+1 = caracter logo após '='.
registradores->at(3) = atualizado;
return;
}
else // se não for registrador, está atualizando memória
{
// atualizado recebe o valor de memória
// Exemplo de atualização na memória: MEM[128]=10101010
atualizado = linha.substr(linha.find_first_of('[')+1, 3);
string valor = linha.substr(posicao+1); // valor em binário que vai substituir o antigo
mem->at(atoi(atualizado.c_str())) = valor; // atualiza o endereço de memória
return;
}
/// c_str -> transforma a string em um arraid char
/// atoi -> transforma string em inteiro. recebe vetor de char.
}
else // LDR
{
//Exemplo: LDR AC, 128
size_t posicaoPrimEspaco = linha.find_first_of(" "); // usado para achar o registrador a ser atualizado
size_t posicaoUltEspaco = linha.find_last_of(" "); // usado para achar com o que o registrador será atualizado
string conteudoCarregado; // valor que será implementado no registrador
switch (linha[++posicaoUltEspaco]) // acha o conteúdo que será atribuído ao registrador
{
case '[': { // Endereçamento Indireto
// strValor recebe valor dentro de colchetes. Ex.: [128],
string strValor = linha.substr(++posicaoUltEspaco, linha.find_first_of(']'));
unsigned int enderecoMem = atoi(strValor.c_str());
strValor = mem->at(enderecoMem); // strValor agora tem o conteúdo do endereço de mem. explicitado na linha de comando,
// Ex.: o valor contido na memória de 128, que será um novo valor de memória.
enderecoMem = ConverteBinarioUnsigned(strValor); // enderecoMem tem agora o valor em dec. do end. de mem. que era apontado
// pelo valor dentro dos colchetes.
conteudoCarregado = mem->at(enderecoMem);
break;
}
case '#': { // Endereçamento Imediato
string strValor = linha.substr(++posicaoUltEspaco); // pega o valor após # (str de números).
int valor = atoi(strValor.c_str());
conteudoCarregado = ConverteDecimal(valor);
break;
}
case 'I': { // Enderaçamento Indexado
posicaoUltEspaco+=3; // pula para onde o número está na string. posUltEsp = I+3 = N em (IC+NUM).
string strEnderecoMem = linha.substr(posicaoUltEspaco); // pega a sequencia de números na string (como 128).
string valorIC = registradores->at(3); // string valorIC recebe o valor de IC.
// enderecoMem recebe o valor apontado pela memória em IC+END
unsigned int enderecoMem = (atoi(strEnderecoMem.c_str())) + ConverteBinarioSigned(valorIC);
conteudoCarregado = mem->at(enderecoMem);
break;
}
default: { // Indereçamento Direto
string strEnderecoMem = linha.substr(posicaoUltEspaco); // string com o endereço
unsigned int enderecoMem = atoi(strEnderecoMem.c_str()); // transforma a string em int
conteudoCarregado = mem->at(enderecoMem); // carrega o valor da memoria
break;
}
}
switch (linha[++posicaoPrimEspaco]) // o switch identifica qual registrador será atualizado
{
case 'A':
registradores->at(0) = conteudoCarregado;
break;
case 'B':
registradores->at(1) = conteudoCarregado;
break;
case 'C':
registradores->at(2) = conteudoCarregado;
break;
case 'I':
registradores->at(3) = conteudoCarregado;
break;
}
}
}
|