Есть несколько проблем в игре здесь:
Всех типов простых прыжков, будь то условный (je
, jne
, и так далее) или безусловный (jmp
), существует в двух формах, коротких и близких, где первый имеет подписанное смещение по размеру байта (диапазон от -128 до +127), а у последнего есть подписанное смещение размера слова (диапазон от -2147483648 до +2147483647).
Изменение условия при условном переходе не требует изменения размера перехода, но изменение целевого адреса прыжка может привести к тому, что желаемый целевой адрес будет за пределами допустимого диапазона.
Если вы хотите на самом деле изменить цель перехода на новое место, находящееся вне диапазона текущего типа перехода, или вставить дополнительные инструкции на сайт кода, вам нужно будет переместить код, который приходит после него.
Как вы подозреваете, это связано с устранением всех относительных ссылок, которые охватывают новый пробел в коде, а также любые абсолютные ссылки, которые следуют за этим разрывом, и если ссылка на то, что ссылается, также перемещается, а также абсолютные ссылки, которые приходят перед разрывом.
Трудность такой операции идет от умеренно сложного к невозможному, в зависимости от того, насколько хорошо структурирован код и какая у вас информация.
Если код, о котором идет речь, был выпущен компилятором, и у вас есть доступная информация о символе, это может быть сделано, в противном случае это обычно очень сложно, если только требуемые изменения очень малы.
Какой компилятор вы используете? – zx485
Это не имеет значения, поскольку вопрос теоретический, но я использовал https://www.onlinedisassembler.com/odaweb/, чтобы получить эти коды операций. – alexandernst
Я написал код, чтобы сделать именно это в прошлом, но он был довольно сложным, поскольку мне приходилось писать базовый opcode dissasembler для идентификации и исправления ссылок. Я подошел к нему немного по-другому, но вместо добавления инструкций я выделил больше бара, скопировал ассемблер, который будет перезаписан инструкцией длинного перехода, а затем обновил все ссылки в моем скопированном ассемблере, чтобы он мог быть выполнен из нового местоположение (на лету PIC). Скачок был направлен на мой новый метод, который затем мог наследовать код старого метода, перепрыгнув на модифицированный сборщик, который я скопировал. – Geoffrey