Я пытаюсь добавить несколько строк asm в программу на Си (просто для удовольствия, играя с ней), чтобы изменить адрес возврата функции.
Не.
Для кода, написанного на C;компилятор владеет стеком, компилятор генерирует код запуска функции для себя и своих оптимизаций, а компилятор генерирует код выхода в соответствии со своим собственным кодом запуска.Любая встроенная сборка, которая делает какие-либо предположения о расположении стека, является «хрупкой» - крошечное изменение в любом месте (даже просто изменение невинной локальной переменной, изменение аргумента командной строки компилятора или обновление компилятора до следующей версии) может и в конечном итоге приведет кРазличия в расположении стека, которые могут нарушить встроенную сборку.На практике это на самом деле намного хуже, чем это - компилятор может и будет генерировать несколько разных версий одной и той же «функции C» (и встроить некоторые версии в другие функции, чтобы избежать затрат на вызов функции и т. Д.), Так что вы в конечном итоге получитеодин и тот же фрагмент встроенной сборки, который пытается (и гарантированно потерпит неудачу) обрабатывать несколько совершенно разных макетов стека;и даже если вы успешно вернетесь куда-то еще, вы не сможете надежно избежать путаницы после того, как ваша функция вернулась.
Другая проблема заключается в том, что почти никогда не бывает разумной причины хотеть сделать это в первую очередь;даже если вы пишете на ассемблере, где у вас есть полный контроль над компоновкой стека (и не пишете на языке C на встроенном ассемблере, где вы не можете контролировать компоновку стека).
По существу;есть чрезвычайно большое количество вещей, которые более важны для того, кто пытается изучать ассемблер, чтобы тратить свое время на изучение (которые не являются «хрупкими» и бесполезными).Это похоже на то, как учиться водить машину, стоя на руках (используя лицо на педали акселератора / тормоза и не видя ничего вокруг себя) - это бесполезно.