Перейти к содержанию

    

Самомодифицирующийся код в экосистеме Cortex-M.

Есть мысль использовать самомодифицирующийся код для оптимизации решения одной задачи.

Именно самомодифицирующийся - программа строит часть самой себя по некоему алгоритму, а не просто копирует куски кода из одной области памяти в другую.

И вот я что-то не смог вспомнить чтобы здесь на форуме вообще когда-то поднималась эта тема.

Кто-то вообще использует такой код на ARM-ах в своих проектах? Просто интересно... :rolleyes:

 

PS: И пожалуйста - без религиозной нетерпимости.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
И вот я что-то не смог вспомнить чтобы здесь на форуме вообще когда-то поднималась эта тема.

Кто-то вообще использует такой код на ARM-ах в своих проектах? Просто интересно... :rolleyes:

Просто тема в принципе не частая. А так - почему бы и нет, если позволяет эффективно решить задачу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Просто интересно... :rolleyes:

Начнём с того что для успешной компиляции такого кода - необходимы пляски с бубном. И бубен тот особенный, очень неудобный в руках. И танец чуть больше чем чумашедший.

Информации на эту тему раз/два и обчёлся, и всё такое ветхое - пылью покрытое.

Всё дело в том что сама функция изменения физического и логического поведения кода на кортексах работает из коробки. Коробка сея чёрная, на свет не прозрачная, и достаточно уникальная.

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

 

Но выход есть всегда.

На Си, Си++, и выше - задать точную последовательность применения мнемоник ядра практически невозможно. Однако это можно сделать на асме.

Весь проект придётся делить на две части: до и после. Причём компилировать придётся то-же отдельно. Весьма утомительное удовольствие.

 

Если нет задачи защиты информации - этим рукоблудием лучше не заниматься.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
На Си, Си++, и выше - задать точную последовательность применения мнемоник ядра практически невозможно. Однако это можно сделать на асме.

Ужасы какие. ТС вроде как собирался генерировать часть кода программно с нуля, а не строить новую программу из частей исходной. Термин "самомодифицирующийся", возможно, не самый удачный, но предполагает обычно именно это.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не предполагает.

Любая перетасовка программного кода - есть алгоритм. Ничего сложного, местами даже интересно, в плюсах вообще всё прозрачно получается.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Давайте сначала:

 

Всё дело в том что сама функция изменения физического и логического поведения кода на кортексах работает из коробки.

О какой магической функции речь? И что есть физическое и логическое поведение кода?

 

Создавая собственный свод правил для определений поведения кода в режиме реального времени исполнения...

Свод правил для определений поведения - это как?

 

Любая перетасовка программного кода - есть алгоритм. Ничего сложного, местами даже интересно, в плюсах вообще всё прозрачно получается.

Плюса-то здесь каким боком?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Начнём с того что для успешной компиляции такого кода - необходимы пляски с бубном.

Это ещё почему?

Компилятор вообще по барабану: он не знает, что за программу (какого назначения) он компилит.

 

 

Ужасы какие. ТС вроде как собирался генерировать часть кода программно с нуля, а не строить новую программу из частей исходной. Термин "самомодифицирующийся", возможно, не самый удачный, но предполагает обычно именно это.

Да банально заменить во флеше JMP +10 на JMP +20 в процедуре - вот уже самомодифицирующийся код.

Делал так.

 

Зачем так делать? Почему бы не сделать команду условного перехода, которая будет делать переход в зависимости от некоего доп. флажка?

 

Из экономии тактов и битов

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Есть мысль использовать самомодифицирующийся код для оптимизации решения одной задачи.

 

Никто не запрещает. Если хорошо владеете темой, то единственные грабли - это кэш.

 

И вот я что-то не смог вспомнить чтобы здесь на форуме вообще когда-то поднималась эта тема.

 

Нынче памяти много, проще вызывать готовые оптимизированные куски.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Начнём с того что для успешной компиляции такого кода - необходимы пляски с бубном.

Какая компиляция? Я же написал: код будет строить моя программа (на этом же Cortex-M). Т.е. - она сразу будет создавать функцию в машинных кодах (если так понятнее). Которая после будет вызываться.

 

На Си, Си++, и выше - задать точную последовательность применения мнемоник ядра практически невозможно.

Не понял - в чём сложность? Алгоритм создания кода вполне себе тривиальный.

 

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

Да, именно так. Будет функция (написанная и скомпилённая обычным образом), которая в некоем буфере будет "писать" другую функцию прямо в машинных кодах.

 

Из экономии тактов и битов

Да. Тактов. Думал и так и эдак - как оптимизировать требуемый алгоритм чтобы он был как можно быстрее. Но классическими методами не получается никак. А потом в голову пришла мысль что это легко делается самомодифицирующимся кодом.

Эта функция должна вызываться с довольно большой частотой из ISR. Отсюда и желание оптимизации.

 

Никто не запрещает. Если хорошо владеете темой, то единственные грабли - это кэш.

Кеш мы победим. :rolleyes:

 

Нынче памяти много, проще вызывать готовые оптимизированные куски.

Тогда таких кусков придётся написать 2^64 (это не операция XOR). :smile3009: Я же говорю - классическими методами не получается придумать оптимального решения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
О какой магической функции речь? И что есть физическое и логическое поведение кода?

Cortex, да и почти все arm чипы - используют внеочередное исполнение кода. Он может загружать адреса для двух функций одновременно. Просчитывать данные которые будут применяться где-то внутри функции до её реального вызова. Размазывать циклы на всю портянку. Обращать переменные в другое значение чем было назначено в пользовательской программе -без потери целостности алгоритма, и ещё много много чего. Это их главная фишка.

Фактически код в отладчике выполняется по строкам программы, а в реальности прыгает как бешеный сайгак.

 

Попытка воткнуть модификацию кода без предварительной изоляции всего куска - обычно приводит быстрому и окончательному сбою.

 

Свод правил - прикольная вещь. Кусок кода предварительно компилируется в асму, с сохранением всех имён, названий функций и так далее. На весь этот кусок кода накладывается структура - с достаточно детальным описанием, прежде всего для себя (запутаться проще простого). И только после этого компилятор поймёт - чего от него хотят.

Код который будет модифицировать этот кусок асмы - будет автоматически подстраиваться под имеющиеся логический цикл. Это означает что компилятор не воткнёт команды предварительного чтения на модифицированный код, корректно сделает переход, и корректно обработает замену кода и данных на которые он будет ссылаться.

Есно остальной код без модификаций - если он уже вызывал некоторые функции из этого блока - то потеряет адреса. Не просто так - а сработают заглушки по внешнему флагу.

 

В плюсах такие модификации кода происходят автоматически при сборке функции. Когда код выполняется из памяти - там вообще трудно чего понять. (по крайней мере мне).

 

 

 

 

 

 

 

Компилятор вообще по барабану: он не знает, что за программу (какого назначения) он компилит.

Естественно.

Но если нужно модифицировать код - то требования повышаются. Компилятору нужно будет объяснить - где и чего менять, и как это скажется на его дальнейшей работе.

 

 

Какая компиляция? Я же написал: код будет строить моя программа (на этом же Cortex-M). Т.е. - она сразу будет создавать функцию в машинных кодах (если так понятнее). Которая после будет вызываться.

 

Кхм, это наверное слишком глупо, но всё-же.

Флешка - это именно та флешка что вставляется в разъём компьютера?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Cortex, да и почти все arm чипы - используют внеочередное исполнение кода. Он может загружать адреса для двух функций одновременно. Просчитывать данные которые будут применяться где-то внутри функции до её реального вызова. Размазывать циклы на всю портянку. Обращать переменные в другое значение чем было назначено в пользовательской программе -без потери целостности алгоритма, и ещё много много чего. Это их главная фишка.

Тем не менее - количество чтений/записей из/в память которые нужно выполнить всё равно не уменьшится, менее чем требующееся по алгоритму, при любом оптимизаторе.

А перевод на самомодифицирующийся код сокращает это количество многократно.

Уж что-что, а ассемблер для Cortex-M я знаю неплохо. И пока не сделали такой оптимизатор, который напишет код лучше меня. :rolleyes:

 

Флешка - это именно та флешка что вставляется в разъём компьютера?

Вы о чём? :wacko:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
PS: И пожалуйста - без религиозной нетерпимости.

Обещать не могу. :biggrin:

 

А загрузчики считаются самомодифицирующимся кодом?

Или самомодифицирующийся - это код который вот именно сам себя модифицирует, т.е. инструкция STR вот прямо по своему адресу что-то и пишет и сама себя таким образом затирает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Или самомодифицирующийся - это код который вот именно сам себя модифицирует, т.е. инструкция STR вот прямо по своему адресу что-то и пишет и сама себя таким образом затирает.

Я уже выше написал: будет функция, которая по некоторым условиям пишет другую функцию. По командам. В маш.кодах. Команды записываемые в тело создаваемой функции (и их последовательность) зависят от аргументов первой функции.

 

PS: Вот уже сколько откликов получил, а на собственно единственный вопрос, поставленный в первом сообщении, так никто и не ответил. И видимо забыли все в чём был вопрос..... :(

Вопрос был собственно в том: использовал кто-нить из здесь присутствующих самомодифицирующийся код (именно такой код, который или сам своё тело правит или строит другой код (а не просто копирует из одного места в другое))? Именно на платформе ARM в embedded?

И, если использовали, то для какой задачи?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Я уже выше написал: будет функция, которая по некоторым условиям пишет другую функцию. По командам. В маш.кодах. Команды записываемые в тело создаваемой функции (и их последовательность) зависят от аргументов первой функции.

Тогда я не согласен с названием "самомодифицирующийся", у меня загрузчики тоже загружают разные не то что функции, а целые программы(и да в машинных кодах, разумеется) в зависимости от аргументов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Тогда я не согласен с названием "самомодифицирующийся", у меня загрузчики тоже загружают разные не то что функции, а целые программы(и да в машинных кодах, разумеется) в зависимости от аргументов.

Ну хорошо - придумайте своё название. :rolleyes: Не в терминах суть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти