имеется MIPS бинарник, исходный код на C, компилятор GNU C 2.9-что-то (версия где-то 96-98 года), платформа PSX.
В коде определена функция — декомпрессор LZ77 формата, состоящий из следующих блоков:
1. Аллокация памяти для несжатых данных
2. Помещение в регистры указателей на начало выделеной памяти и на начало сжатых данных
3. Собственно декомпрессия
В большинстве мест эта функция вызывается нормально, JAL'ом в начало пролога, но в одном месте в адресе вызова указано не начало, а адрес п.3, т.е. вызов происходит по следующему сценарию:
1. В регистры помещается адрес статического буффера и сжатых данных (т.е. пропускается этап аллокации внутри функции которая будет вызвана)
2. Вызов функции декомпрессии, но адрес вызова не в начало, а п.3
Я совершенно не понимаю, что такое могли написать оригинальные авторы кода, чтобы компилятор создал такой переход, тем более что во всех мануалах по MIPS которые я встречал чётко прописано что JAL должен быть совершён в начало пролога функции(хотя конечно никто не запрещает прописать любой адрес).
Что я попробовал:
1. Простое goto естественно не работает по причине области видимости меток.
2. longjmp/setjmp генерирует другой код, с явным вызовом этих функций.
3. Извращение со специфичным для GCC взятием указателя на метку создаёт похожий код, но всё-же вычисляет адрес куда прыгать, а не знает его уже заранее. Возможно, это я что-то делаю не так, но из-за особенности областей видимости сделать константный указатель на метку у меня не получается.
Что у меня пока не получается точно проверить такие теории:
1. Это какой-то очень хитрый инлайнинг.
2. Часть функции декомпрессии определена как макрос(например, но это пальцем в небо) и компилятор понял что этот код вставлен в два места и положил в бинарник его только один раз.
3. Ручками написанный asm в сишном исходнике, специально для этого случая.
Может быть кто-то встречал такое или может предложить что в C коде теоретически может к такому привести? Мне кажется, что в условиях сурового эмбеда авторы кода меньше всего хотели писать какие-то хитрые хаки ради вполне стандартной задачи, которую можно было решить просто разнесением функции декомпрессии на две, и это скорее всего оптимизация компилятора...
Первое (да сбоственно и единственное), что приходит в голову — оптимизация. Раз адрес известен заранее, значит компилятор его уже у себя в таблицы засунул.
Re: Какой код мог привести к генерации JAL в середину функции в MIPS бинарнике
Здравствуйте, netch80, Вы писали:
N>Учти ещё, что обычно высокие уровни оптимизации рассчитываются на ускорение по времени за счёт разбухания кода. Для ужатия кода нужна опция -Os.
Я так понимаю, что исходники недоступны. Были бы доступны, ТС просто посмотрел что написано в том странном месте висходниках...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Какой код мог привести к генерации JAL в середину функции в MIPS бинарник
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, netch80, Вы писали:
N>>Учти ещё, что обычно высокие уровни оптимизации рассчитываются на ускорение по времени за счёт разбухания кода. Для ужатия кода нужна опция -Os.
E>Я так понимаю, что исходники недоступны. Были бы доступны, ТС просто посмотрел что написано в том странном месте висходниках...
Исходники недоступны, иначе всё было-бы тривиально, поэтому и приходится выдумывать
Re[2]: Какой код мог привести к генерации JAL в середину функции в MIPS бинарник
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, overkrik, Вы писали:
O>>Что у меня пока не получается точно проверить такие теории: O>>1. Это какой-то очень хитрый инлайнинг.
N>Это вероятнее всего. Проверяется снижением уровня оптимизации, явным запретом inline в опциях компиляции.
N>Учти ещё, что обычно высокие уровни оптимизации рассчитываются на ускорение по времени за счёт разбухания кода. Для ужатия кода нужна опция -Os.
У меня к сожалению нет исходника и в этом вся проблема, но за -Os спасибо, попробую посмотреть, что будет в бинарник попадать с моими тестами.