示例#1
0
 def insert(self, line):
   """ Parse the given data line and insert its values in our memory. """
   name, dtype, values = line.split(None, 2)
   name, dtype, values = name[:-1], dtype[1:].lower(), [v.strip() for v in values.split(",")]
   if dtype not in ["ascii", "asciiz", "byte", "halfword", "word", "space"]:
     raise ValueError("Invalid data type: {0}".format(dtype))
   self.labels[name] = self.offset
   if dtype == "space":
     self.offset += getimm(values[0], True)
   else:
     for value in values:
       self[self.offset] = value if "ascii" in dtype else getimm(value, True)
       self.offset += 1
示例#2
0
 def runMIPS(self):
   """ Execute the program using the MIPS instruction set. """
   HI, LO = 0, 0
   cur_line = 0
   while cur_line < len(self.instructions):
     instr = self.instructions[cur_line]
     if cur_line in self.labels.values(): pass
     elif instr.operation in ["add", "addu"]:
       self.registers[instr.operand0] = self.registers[instr.operand1] + self.registers[instr.operand2]
     elif instr.operation == "addi":
       self.registers[instr.operand0] = self.registers[instr.operand1] + getimm(instr.operand2, True)
     elif instr.operation == "addiu":
       self.registers[instr.operand0] = self.registers[instr.operand1] + getimm(instr.operand2, False)
     elif instr.operation == "and":
       self.registers[instr.operand0] = self.registers[instr.operand1] & self.registers[instr.operand2]
     elif instr.operation == "andi":
       self.registers[instr.operand0] = self.registers[instr.operand1] & getimm(instr.operand2, False)
     elif instr.operation == "beq":
       if self.registers[instr.operand0] == self.registers[instr.operand1]:
         cur_line = self.labels[instr.operand2] # jump straight to the label rather than the following instruction because we increment the line counter at the end anyway
     elif instr.operation == "bgez":
       if self.registers[instr.operand0] >= 0:
         cur_line = self.labels[instr.operand1]
     elif instr.operation == "bgezal":
       if self.registers[instr.operand0] >= 0:
         self.registers[31] = cur_line + 1
         cur_line = self.labels[instr.operand1]
     elif instr.operation == "bltz":
       if self.registers[instr.operand0] < 0:
         cur_line = self.labels[instr.operand1]
     elif instr.operation == "bltzal":
       if self.registers[instr.operand0] < 0:
         self.registers[31] = cur_line + 1
         cur_line = self.labels[instr.operand1]
     elif instr.operation == "bne":
       if self.registers[instr.operand0] != self.registers[instr.operand1]:
         cur_line = self.labels[instr.operand2]
     elif instr.operation in ["div", "divu"]:
       LO = self.registers[instr.operand0] // self.registers[instr.operand1]
       HI = self.registers[instr.operand0] % self.registers[instr.operand1]
     elif instr.operation == "j":
       cur_line = self.labels[instr.operand0]
     elif instr.operation == "jal":
       self.registers[31] = cur_line + 1
       cur_line = self.labels[instr.operand0]
     elif instr.operation == "jr":
       cur_line = self.registers[instr.operand0]
     elif instr.operation == "la":
       self.registers[instr.operand0] = self.memory.labels[instr.operand1]
     elif instr.operation in ["lb", "lw"]:
       outside, inside = parse_address(instr.operand1)
       address = calcval(outside, self) + calcval(inside, self)
       self.registers[instr.operand0] = self.memory[address]
     elif instr.operation == "lui":
       self.registers[instr.operand0] = getimm(instr.operand1, False) << 16
     elif instr.operation == "mfhi":
       self.registers[instr.operand0] = HI
     elif instr.operation == "mflo":
       self.registers[instr.operand0] = LO
     elif instr.operation in ["mult", "multu"]:
       LO = self.registers[instr.operand0] * self.registers[instr.operand1]
     elif instr.operation == "nor":
       self.registers[instr.operand0] = ~(self.registers[instr.operand1] | self.registers[instr.operand2]) & 0xFFFFFFFF
     elif instr.operation == "or":
       self.registers[instr.operand0] = self.registers[instr.operand1] | self.registers[instr.operand2]
     elif instr.operation == "ori":
       self.registers[instr.operand0] = self.registers[instr.operand1] | getimm(instr.operand2, False)
     elif instr.operation == "sb":
       outside, inside = parse_address(instr.operand1)
       address = calcval(outside, self) + calcval(inside, self)
       self.memory[address] = self.registers[instr.operand0] & 0xFF
     elif instr.operation in ["slt", "sltu"]:
       self.registers[instr.operand0] = int(self.registers[instr.operand1] < self.registers[instr.operand2])
     elif instr.operation == "slti":
       self.registers[instr.operand0] = int(self.registers[instr.operand1] < getimm(instr.operand2, True))
     elif instr.operation == "sltiu":
       self.registers[instr.operand0] = int(self.registers[instr.operand1] < getimm(instr.operand2, False))
     elif instr.operation == "sll":
       self.registers[instr.operand0] = self.registers[instr.operand1] << getimm(instr.operand2, False)
     elif instr.operation == "sllv":
       self.registers[instr.operand0] = self.registers[instr.operand1] << self.registers[instr.operand2]
     elif instr.operation == "sra":
       self.registers[instr.operand0] = self.registers[instr.operand1] >> getimm(instr.operand2, True)
     elif instr.operation == "srl":
       self.registers[instr.operand0] = self.registers[instr.operand1] >> getimm(instr.operand2, False)
     elif instr.operation == "srlv":
       self.registers[instr.operand0] = self.registers[instr.operand1] >> self.registers[instr.operand2]
     elif instr.operation in ["sub", "subu"]:
       self.registers[instr.operand0] = self.registers[instr.operand1] - self.registers[instr.operand2]
     elif instr.operation == "sw":
       outside, inside = parse_address(instr.operand1)
       address = calcval(outside, self) + calcval(inside, self)
       self.memory[address] = self.registers[instr.operand0]
     elif instr.operation == "syscall":
        retval = mips_syscall(self.registers[2])
        if retval: break
     elif instr.operation == "xor":
       self.registers[instr.operand0] = self.registers[instr.operand1] ^ self.registers[instr.operand2]
     elif instr.operation == "xori":
       self.registers[instr.operand0] = self.registers[instr.operand1] ^ getimm(instr.operand2, False)
     elif instr.operation == "break":
       break
     else:
       raise ValueError("Unrecognized operation: {0}".format(instr.operation))
     cur_line += 1
   return self