Самоизменяющийся код MIPS

Я пытаюсь написать программу на MIPS, которая постоянно запрашивает два целых числа и печатает сумму до тех пор, пока сумма не станет 0. Хитрость заключается в том, что если сумма равна 13, мне нужно вызвать метод, чтобы изменить собранный код MIPS так, чтобы

add $t2, $t0, $t1

становится

and $t2, $t0, $t1

и во всех последующих запусках цикла используется инструкция and.

У меня есть цикл суммирования, работающий так, что когда сумма равна 13, вызывается метод instMod, который я хочу изменить в инструкции. К сожалению, я не знаю, с чего начать, и не могу найти никаких примеров этого онлайн. Я предполагаю, что мне нужно каким-то образом получить шестнадцатеричный код дополнения из собранного кода и заменить его шестнадцатеричным кодом для и, но я не знаю, как это сделать, или это правильный путь действий.

# Nick Gilbert
# MIPS Program to demonstrate self-modifying code

.data
num1Prompt:     .asciiz     "Enter num1: "
num2Prompt:     .asciiz     "Enter num2: "
num1:           .word       0
num2:           .word       0
addOut:         .asciiz     "ADD: "
andOut:         .asciiz     "AND: "

.text
main:
sumLoop:
    la $a0, num1Prompt  #Asking user for num1
    li $v0, 4       #Call code to print string
    syscall     

    li $v0, 5       #Call code to read an int
    syscall
    move $t0, $v0       #Moving read int to $t1

    la $a0, num2Prompt  #Asking user for num2
    li $v0, 4       #Call code to print string
    syscall

    li $v0, 5       #Call code to read an int
    syscall
    move $t1, $v0       #Moving read int to $t2

    add $t2, $t0, $t1   #Adding num1 and num2 together

    la $a0, addOut
    li $v0, 4
    syscall

    move $a0, $t2
    li $v0, 1
    syscall

    beq $t2, 13, instMod    #Calling method to modify add instruction if sum = 13
    bne $t2, 0, sumLoop #If result is not yet 0, ask for new sum

endSumLoop:
    li $v0, 10
    syscall

instMod: #Method to change add instruction to an and instruction

2 ответа

Решение

Добавьте метку в инструкции, которую вы хотите заменить, например:

instruction_to_be_replaced:
  add $t2, $t0, $t1   #Adding num1 and num2 together

тогда в твоей рутине instMod

instMod: #Method to change add instruction to an and instruction
    lw $t1, instruction_to_replace
    sw $t1, instruction_to_be_replaced
    j sumLoop  # go back to your sumLooop

instruction_to_replace:
    and $t2, $t0, $t1

Код загружается во временный реестр $t1 содержание инструкции, которую вы хотите заменить, а затем сохраняет ее в месте, помеченном instruction_to_be_replaced,

"Источник" инструкции помечен в инструкциях.

Для этого вам нужно иметь возможность писать в разделе кода, который, как я полагаю, у вас есть, иначе вы бы не задавали этот вопрос.

Попробуй это:

  1. Соберите инструкцию, которая вам нужна в объектный файл
  2. Извлечь шестнадцатеричное из эквивалентного машинного кода
  3. Поместите метку перед кодом, который нужно изменить
  4. mov шестнадцатеричное от шага 2 в место с шага 3 в вашем instMod раздел

Для этого две инструкции с операндами должны иметь одинаковую длину. Если это не так, добавьте оригинал или замену nop по мере необходимости.

Другие вопросы по тегам