Macchina MIPS
📖 Guida all'uso e Istruzioni Supportate
⚠️ Nota Didattica: Questo simulatore è progettato a scopo educativo. Il funzionamento della memoria RAM e dei registri è stato semplificato rispetto all'architettura reale e alcune istruzioni avanzate del MIPS non sono implementate.
Informazioni generali:
Registri: Puoi utilizzare i registri standard (es. $t0-$t9, $s0-$s7, $a0-$a3, $v0-$v1, $sp, $ra). Ricorda che $zero contiene sempre il valore 0.
RAM: È gestita come un array con indirizzi che vanno da 0 a 65536. Se cerchi di accedere ad un indirizzo fuori da questo range, il programma si fermerà per errore.
Istruzioni disponibili:
add: add $t0, $s2, $s7 (Somma $s2 e $s7, salva in $t0)
addi: addi $t0, $zero, 15 (Somma 15 a $zero, salva in $t0)
sub: sub $t0, $s2, $s7 (Sottrae $s7 da $s2, salva in $t0)
and / andi: and $t0, $s1, $s2 (Esegue l'AND logico bit a bit)
or / ori: or $t0, $s1, $s2 (Esegue l'OR logico bit a bit)
xor: xor $t0, $s1, $s2 (Esegue lo XOR logico bit a bit)
nor: nor $t0, $s1, $s2 (Esegue il NOR logico bit a bit)
sll: sll $t0, $s1, 2 (Sposta a sinistra di 2 bit)
slt / slti: slt $t0, $s1, $s2 (Se $s1 < $s2, allora $t0 diventa 1, altrimenti 0)
beq: beq $t0, $t1, loop (Salta all'etichetta 'loop' se $t0 è uguale a $t1)
bne: bne $t0, $t1, loop (Salta all'etichetta 'loop' se $t0 è diverso da $t1)
j: j loop (Salto incondizionato all'etichetta 'loop')
jal: jal funzione (Salta all'etichetta e salva l'indirizzo di ritorno in $ra)
jr: jr $ra (Ritorna all'indirizzo salvato nel registro $ra)
lw: lw $t0, 4($s1) (Carica in $t0 il dato presente nella RAM all'indirizzo $s1 + 4)
sw: sw $t0, 4($s1) (Salva il valore di $t0 nella RAM all'indirizzo $s1 + 4)
Esempio
Inserisci il codice assembly MIPS da eseguire:
Esegui
Interrompi
Mostra RAM
Stampa stato registri ad ogni istruzione
from pyscript import Element
import asyncio
fine = False
ram = {}
def init_registri():
reg = {
"$zero":0, "$at":0, "$v0":0, "$v1":0,
"$a0":0, "$a1":0, "$a2":0, "$a3":0,
"$t0":0, "$t1":0, "$t2":0, "$t3":0, "$t4":0, "$t5":0, "$t6":0, "$t7":0,
"$s0":0, "$s1":0, "$s2":0, "$s3":0, "$s4":0, "$s5":0, "$s6":0, "$s7":0,
"$t8":0, "$t9":0,
"$sp":65536, "$fp":65536, "$ra":0
}
return reg
async def execute_mips(event):
global fine
global ram
fine = False
Element("interrompi").element.style.display = "block"
output = Element("output")
output.element.innerHTML = "Avvio Esecuzione... "
registri = init_registri()
ram = {}
pc = 0
code = Element("code-input").element.value.strip().lower()
if code == "":
output.element.innerHTML += "Non è stato inserito nessun codice "
Element("interrompi").element.style.display = "none"
return
righe_codice = code.split("\n")
associazioni_etichette = {}
for c, istruzione in enumerate(righe_codice):
if ":" in istruzione:
associazioni_etichette[istruzione.split(":")[0].strip()] = c
c_istruzioni = 0
while pc < len(righe_codice):
if fine:
output.element.innerHTML += "Programma interrotto. "
break
await asyncio.sleep(0.01)
if c_istruzioni > 10000:
output.element.innerHTML += "Sono state eseguite più di 10000 istruzioni, il programma è stato interrotto. "
break
istruzione_raw = righe_codice[pc]
istruzione = istruzione_raw.replace(" ", "").replace("\t", "").split("#")[0]
if ":" in istruzione:
istruzione = istruzione.split(":")[1]
if istruzione == "":
pc += 1
continue
output.element.innerHTML += f"Riga {pc + 1}: {istruzione_raw.split('#')[0].strip()} "
try:
if istruzione.startswith("addi"):
parti = istruzione[4:].split(",")
registri[parti[0]] = registri[parti[1]] + int(parti[2])
elif istruzione.startswith("add"):
parti = istruzione[3:].split(",")
registri[parti[0]] = registri[parti[1]] + registri[parti[2]]
elif istruzione.startswith("sub"):
parti = istruzione[3:].split(",")
registri[parti[0]] = registri[parti[1]] - registri[parti[2]]
elif istruzione.startswith("slti"):
parti = istruzione[4:].split(",")
registri[parti[0]] = int(registri[parti[1]] < int(parti[2]))
elif istruzione.startswith("slt"):
parti = istruzione[3:].split(",")
registri[parti[0]] = int(registri[parti[1]] < registri[parti[2]])
elif istruzione.startswith("jal"):
registri["$ra"] = ((pc) * 4) + 4
pc = associazioni_etichette[istruzione[3:]] - 1
elif istruzione.startswith("jr"):
pc = int(registri["$ra"]) // 4 -1
elif istruzione.startswith("j") and not istruzione.startswith("jal"):
pc = associazioni_etichette[istruzione[1:]] - 1
elif istruzione.startswith("beq"):
parti = istruzione[3:].split(",")
if registri[parti[0]] == registri[parti[1]]:
pc = associazioni_etichette[parti[2]] - 1
elif istruzione.startswith("bne"):
parti = istruzione[3:].split(",")
if registri[parti[0]] != registri[parti[1]]:
pc = associazioni_etichette[parti[2]] - 1
elif istruzione.startswith("sll"):
parti = istruzione[3:].split(",")
registri[parti[0]] = registri[parti[1]] << int(parti[2])
elif istruzione.startswith("lw"):
parti = istruzione[2:].split(",")
x = parti[1].split("(")
indirizzo = int(x[0]) + registri[x[1][:-1]]
if 0 <= indirizzo <= 65536:
registri[parti[0]] = ram.get(indirizzo, 0)
else:
output.element.innerHTML += "Errore: lw non riuscita, indirizzo fuori dalla memoria "
elif istruzione.startswith("sw"):
parti = istruzione[2:].split(",")
x = parti[1].split("(")
indirizzo = int(x[0]) + registri[x[1][:-1]]
if 0 <= indirizzo <= 65536:
ram[indirizzo] = registri[parti[0]]
else:
output.element.innerHTML += "Errore: sw non riuscita, indirizzo fuori dalla memoria "
elif istruzione.startswith("andi"):
parti = istruzione[4:].split(",")
registri[parti[0]] = registri[parti[1]] & int(parti[2])
elif istruzione.startswith("and"):
parti = istruzione[3:].split(",")
registri[parti[0]] = registri[parti[1]] & registri[parti[2]]
elif istruzione.startswith("ori"):
parti = istruzione[3:].split(",")
registri[parti[0]] = registri[parti[1]] | int(parti[2])
elif istruzione.startswith("or"):
parti = istruzione[2:].split(",")
registri[parti[0]] = registri[parti[1]] | registri[parti[2]]
elif istruzione.startswith("xor"):
parti = istruzione[3:].split(",")
registri[parti[0]] = registri[parti[1]] ^ registri[parti[2]]
elif istruzione.startswith("nor"):
parti = istruzione[3:].split(",")
risultato = ~(registri[parti[1]] | registri[parti[2]])
registri[parti[0]] = risultato & 0xFFFFFFFF
else:
output.element.innerHTML += f"Istruzione non riconosciuta Programma interrotto "
break
registri["$zero"] = 0
if Element("vehicle1").element.checked:
reg_mod = {k:v for k,v in registri.items() if v != 0}
output.element.innerHTML += f"Registri attivi: {reg_mod} "
except Exception as e:
output.element.innerHTML += f"Istruzione non riconosciuta (Errore di sintassi) Programma interrotto "
break
pc += 1
c_istruzioni += 1
Element("interrompi").element.style.display = "none"
output.element.innerHTML += f" Fine Numero istruzioni eseguite: {c_istruzioni} "
output.element.innerHTML += f"Registri finali: {registri} "
def interrompi_exec(event):
global fine
fine = True
Element("interrompi").element.style.display = "none"
def mostra_ram(event):
global ram
output = Element("output")
if not ram:
output.element.innerHTML += " Stato RAM: Vuota. "
else:
output.element.innerHTML += f" Stato RAM: "
for ind, val in sorted(ram.items()):
output.element.innerHTML += f"Indirizzo [{ind}] = {val} "
Element("finish-input-btn").element.onclick = execute_mips
Element("interrompi").element.onclick = interrompi_exec
Element("show-ram-btn").element.onclick = mostra_ram