codigo

 avatar
unknown
plain_text
a year ago
6.9 kB
7
Indexable
import argparse


class Interpretador:

	def __init__(self,verbose=False,enderecos_memoria=8):

		self.verbose = verbose
		self.__TAMANHO_BLOCO_MEMORIA_BITS = 32
		self.registradores = None
		self.memoria = None
		self.numero_enderecos_memoria = 2**enderecos_memoria
		self.memoria = None
		self.resetaRegisradores()
		self.resetaMemoria()
		if self.verbose:
			self.statusSistema()
		self.gotos = {}

	def converteHexToDec(self,hex_):
		if '0x' not in hex_:
			raise Exception("ERRO DE INTERPRETACAO: Numero (%s) hexadecimal invalido" % hex_)
		hex_ = list(hex_)
		hex_ = hex_[2:]
		decimal = 0

		for i in range(len(hex_)):
			if hex_[i] in 'abcdef':
				hex_[i] = str(int(ord(hex_[i])-97)+10)
			decimal += (int(hex_[i])*(16**(len(hex_)-1-i)))
		return decimal


	def __linhaInValida__(self,linha):
		if len(linha) == 0 or list(linha)[-1] == ' ' or list(linha)[-1] == '\t':
			return True
		return False

	def __interpretagoto(self,arquivo_linhas):

		for index in range(len(arquivo_linhas)):
			linha = arquivo_linhas[index].strip()
			if self.__linhaInValida__(linha):
				#print('nao processado ',linha)
				continue
			
			if linha[0].isupper() and linha[-1] == ':':
				self.gotos[linha[0:-1]] = index
				

	def interpreta(self,arquivo):

		#asm_code = open(arquivo).read().split('\n')
		self.__interpretagoto(arquivo)
		
		
		index = 0

		while index < len(asm_code):
			linha = asm_code[index].strip()
			if len(linha) == 0 or linha[0] == '#':
				index += 1
				continue

			if self.verbose:
				print('INTERPRETANDO LINHA %d -> %s' % (index,linha))

			if 'db' in linha:
				if '#REG' in linha:
					print(linha.split('#REG')[0])
					self.imprimeRegistros()

				elif '#MEM' in linha:
					print(linha.split('#MEM')[0])
					self.imprimeMemoria()
				elif '#VET' in linha:
					endereco = linha.split('#VET')[1].split()
					self.imprimeVetor(endereco[0],endereco[1])
				else:
					print(' '.join(linha.split()[1:])+'\n')

			elif len(linha.split()) == 3:
				reg1 = linha.split()[1][0:-1]
				reg2 = linha.split()[2]

				

				if 'lui' in linha:
					self.registradores[reg1] = reg2

				elif linha[1] == 'w':

					endereco = reg2
					incremento = endereco.split('(')[0]
					if incremento[0] == 'x':
						incremento = self.registradores[incremento]
					reg2_endereco = endereco.split('(')[1].split(')')[0]

					if 'sw' in linha:
						self.comando_SW(reg1,int(incremento),self.registradores[reg2_endereco])

					elif 'lw' in linha:
						self.comando_LW(reg1,endereco)



			elif len(linha.split()) == 4:
				reg1 = linha.split()[1][0:-1]
				reg2 = linha.split()[2][0:-1]
				reg3 = linha.split()[3]

				if 'addi' in linha:
					self.commando_ADDI(reg1,reg2,reg3)
				elif 'add' in linha:
					self.comando_ADD(reg1,reg2,reg3)
				elif 'sub' in linha:
					self.comando_SUB(reg1,reg2,reg3)

				

				elif  linha[0] == 'b':

					goto_name = reg3

					if 'beq' in linha: #X == Y
						if int(self.registradores[reg1]) == int(self.registradores[reg2]):
							index = self.gotos[goto_name]
					elif 'bne' in linha: #Y != X
						if int(self.registradores[reg1]) != int(self.registradores[reg2]):
							index = self.gotos[goto_name]

					elif 'blt' in linha:
						if int(self.registradores[reg1]) < int(self.registradores[reg2]):
							index = self.gotos[goto_name]

					elif 'bge' in linha:
						if int(self.registradores[reg1]) >= int(self.registradores[reg2]):
							index = self.gotos[goto_name]


			elif len(linha.split()) == 1 and ':' not in linha:
				index = self.gotos[linha.strip()]

			index += 1 
			if self.verbose:
				self.statusSistema()


	def e_endereco(self,reg):
		
		if 'x' in self.registradores[reg]:
			return True
		return False

	def __ACESSA__(self,endereco):
		incremento = endereco.split('(')[0]
		
		endereco = self.registradores[endereco.split('(')[1].split(')')[0]]

		if incremento[0] == 'x':
			incremento = self.registradores[incremento]
		
		return self.memoria[hex(self.converteHexToDec(endereco)+(int(incremento)//4))]

	def comando_ADD(self,reg1,reg2,reg3):


		if self.e_endereco(reg2) or self.e_endereco(reg3):
			print('Nao e permitido operacao aritmetica com enderecos')
			raise Exception()
		self.registradores[reg1] = str(int(self.registradores[reg2])+int(self.registradores[reg3]))

	def comando_SUB(self,reg1,reg2,reg3):
		if self.e_endereco(reg2) or self.e_endereco(reg3):
			print('Nao e permitido operacao aritmetica com enderecos')
			raise Exception()
		self.registradores[reg1] = str(int(self.registradores[reg2])-int(self.registradores[reg3]))

	def commando_ADDI(self,reg1,reg2,numero):
		if self.e_endereco(reg2):
			print('Nao e permitido operacao aritmetica com enderecos')
			raise Exception()
		
		self.registradores[reg1] = str(int(self.registradores[reg2])+int(numero))

	def comando_LUI(self,reg1, numero):
		self.registradores[reg1] = numero

	def comando_SW(self,reg1,incremento,endereco):
		self.memoria[hex(self.converteHexToDec(endereco)+incremento//4)] = self.registradores[reg1]

	def comando_LW(self,reg1,endereco):
		self.registradores[reg1] = self.__ACESSA__(endereco)


	def resetaRegisradores(self):
		self.registradores = dict([('x%d' % d, '0' if d == 0 else None) for d in range(32)])

	def resetaMemoria(self):
		self.memoria = dict([(hex(i),'') for i in range(self.numero_enderecos_memoria)])

	def imprimeRegistros(self):
		print('\n======================================')
		print('---- Status dos registradores ---------')
		
		for reg, dado in self.registradores.items():
			if dado != None:
				print('REG[%s] = %s' % (reg,dado))

	def imprimeMemoria(self):
		print('\n\n---- Status da memoria ---')
		print('INICIO: 0x0000')
		print('FINAL:  0xffff')
		print('ARMAZENAMENTO: %d bytes' % ((self.__TAMANHO_BLOCO_MEMORIA_BITS)*[i != '' for i in self.memoria.values()].count(True)/8))
		memoria_vazia = True
		for endereco, dado in self.memoria.items():
			if dado != '':
				print('ENDERECO[%s] = %s' % (endereco,dado))
				memoria_vazia = False

	def imprimeVetor(self,endereco,tamanho):
		
		vetor = []

		for i in range(int(tamanho)):

			mem = self.memoria[hex(self.converteHexToDec(endereco)+i)]
			if mem == '':
				vetor.append('VAZIA')
			else:
				vetor.append(mem)

		print(vetor)

	def statusSistema(self):
		self.imprimeRegistros()
		self.imprimeMemoria()
		
		

		



	
	# argumentos = argparse.ArgumentParser('Interpretador RISC-V')
	# argumentos.add_argument('--asm',type=str,help="nome do arquivo a ser interpretado")
	# argumentos.add_argument('--verbose',type=int,help="Mensagens")
	# args = argumentos.parse_args()

	# I = Interpretador(args.verbose)
	# I.interpreta(args.asm)
	# #I.statusSistema()
	# #print(I.converteHexToDec(hex(1000)))




Editor is loading...
Leave a Comment