Обновление ... Похоже, этот маленький фрагмент может быть вырезан.
Да, это может быть обрезано , потому что вы скомпилировали без оптимизации , а код обращается только к локальному элементу в стеке.
Но только если перейти к тому же макету стека, что и эта функция, что исключает вызов его как функции. Но да, с вычисленным goto, я думаю, это работает.
Если бы вы обращались к чему-либо в статическом хранилище (константы или глобальные / статические переменные), компиляторы x86-64 использовали бы режимы RIP-относительной адресации, такие как var(%rip)
, которые прервались бы, если бы вы изменили положение кода относительно данные.
Вызовы к другим функциям также прервутся, потому что они скомпилируются в call rel32
, где целевой адрес закодирован относительно сайта вызова.
В целом это вряд ли полезно. Все, что вы могли бы сделать, скопировав блоки неоптимизированного кода, вероятно, можно было бы сделать более эффективно, написав интерпретатор на переносном языке C. Ваша идея очень легко сломается при включенной оптимизации.
Например, если вы хотите увеличить * в 1020 * раз, введение цикла сохранения / перезагрузки добавляет около 5 циклов задержки пересылки хранилища в критический путь, если вы просто скопируете этот блок n
раз.
Кроме того, вам нужно __builtin___clear_cache
в диапазоне, который вы скопировали, если вы хотите включить оптимизацию. И да, это применимо даже к x86, где он на самом деле не очищает кеш, но все же останавливает удаление мертвого хранилища от удаления memcpy
.
Если вы хотите потратить больше времени на создание незавершенного машинного кода, используйте JIT-движок, такой как LLVM.
Ваша идея является жизнеспособной игрушкой / экспериментом в некоторых ограниченных случаях, но я настоятельно рекомендую не использовать ее для любого реального использования, особенно если ваша цель - производительность.