Таким образом, в основном ваша программа будет циклом, который читает одну инструкцию (одну строку во входном файле) * и изменяет свои переменные таким же образом, как инструкция изменяет свои регистры.
Это будет большой «случай переключения» в коде операции, и для каждого случая вы обрабатываете конкретную инструкцию.
Переменные вашей программы в основном будут вашими регистрами, и вам также придется каким-то образом симулировать память (вы должны быть в состоянии выделить всю свою память раз и навсегда как большой кусок памяти, который вы будете обрабатывать) и обрабатывать перевод с адресов MIPS на адреса в вашем фрагменте памяти.
Тогда работа с кодами операций - это в основном вопрос изменения ваших регистров и вашей памяти. Возможно, вы сможете воспользоваться вашим языком для выполнения некоторых операций (например, sum, product, ...), но вам, безусловно, придется обрабатывать немного больше, чем это: например, установите флаги в вашем регистре состояния.
Я не знаком с набором команд MIPS, но вам также может потребоваться выполнить преобразование адресов в зависимости от доступных режимов адресации.
*: На самом деле, это должно быть умнее, чем просто читать входной файл построчно: сначала вы должны загрузить свою программу в этот массив «памяти» и обработать счетчик программ, который будет запускаться при первой инструкции и увеличиваться после обработки текущей инструкции. Иногда поток может переместить ПК назад. В идеале вы также хотели бы сделать эту часть «памяти» неизменяемой, но в первую очередь это не то, на чем вы хотите сосредоточиться.
Надеюсь, я не сказал ничего не относящегося к MIPS.
Итак, с точки зрения структуры, этот псевдокод дает представление:
set all your register variables to their default value
allocate memory for the "memory"
load your program in the "memory"
for (initialize PC ; ??? ; PC"++")
{
read the "memory" at the address in PC -> opcode
switch (opcode)
{
case op1:
handle_op1(); // modify registers and/or "memory", set status register
break;
[...]
}
}