На асме это просто - ставлю метку перед процедурой и после, вычитаю первую из второй. Как то же самое можно сделать на си? Сканирование до первого ret не всегда подходит т.к. бывают процедуры с несколькими ret, или часть процедуры находится за ret.
допусти у тя такая ситуация Код (Text): int some_func() { ..... } int some_func2() { ........ } тогда sizeof.some_func = some_func2 - some_func, хотя я могу ошибаться
Линкер (особенно при оптимизациях) может разместить функции как угодно, то есть может получиться что сперва будет идти some_func2, а за ней уже some_func. Как вариант, можно для тех функций, размер которых тебе нужен, создать секцию - и положить обе функции во вновь сделанную секцию (через plagma_alloc(SECTION, some_func)...).
Android В си тоже можно делать метки и прыгать на них, следовательно можно взять адрес метки и сделать тоже что и в асме!
метками не получится (т.к. метку надо будет размещать вне функции), а если в начале самой функции разместишь метку, она будет недоступна из других функций.
делаю так: добавляю в конец функции строку с помощью _asm _emit , ищу ее в памяти, затем адрес_начала_строки - адрес_функции и будет размер
аа, да, не внимательно прочитал. вам непонятно как значение метки вытащить из функции. тут без извратов или помощи компилятора не выйдет. Но можно.
2KAdot Наверное так проще всего, только нужно характерные строки вставить, например, в начало функции вставляем _asm mov esi, 0ABABABABh в конец _asm mov esi, 0CDCDCDCDh находим разницу, получаем длину с точностью до нескольких байт. Можно оценить более точно путем подъема вверх от первой вставки до первой инструкции функции (это может быть push ebp, например, зависит от компилятора) и спуска вниз до инструкции ret.
Еще один способ. В начало добавляем call $+4 pop esi; esi содержит адрес данной инструкции mov [StartOfFunction], esi в конец call $+4 pop esi; esi содержит адрес данной инструкции sub esi, [StartOfFunction]; получаем длину Опять-таки с точностью до нескольких байт.
если процедура на асм то можно использовать след. код. удобно чтоб узнать размер просто вызываем процедуру только не надо забывать када ходим скопировать её куданить прибавлять 5(размер call L_STUB_END) int __declspec(naked) AsmStub() { __asm { call L_STUB_END } __asm { pushad popad ret } __asm { L_STUB_END: pop eax sub eax, offset L_STUB_END not eax inc eax ret } }
это можно узнать алгоритмом полного дизассемблирования функции (с запоминанием branch'ей). То, что дерматолог слёзно клянчил по форумам типа ренга. Если без учета тонкостей делать, то это несложный алго -- в ~15-30 строк на С. Другой вопрос, зачем это надо. Если компилятор перетасует сами процедуры в коде, это одно, но он может перетасовать и саму процедуру, разбив ее на chunk'и и перемешав с другими процедурами для оптимизации. Тут поможет только такой алго, никакие X - Y и тп тут не прокатят.
если компиль cl можно так: int func_start() { return 1; } void func() { ... } int func_end() { return 2; } ... int len = &func_end-&func_start+C; // C = const
правильный ответ - нельзя длина блока инструкций в байтах есть понятие лежащее ниже уровнем чем любое понятие языка С асм рулез
_BC_ Я не встречал уж слишком крутой перетасовки процедур, в лучшем случае вместо вызова какой-то функции в конце процедуры следует jmp на нее, и то этот метод используется редко. Оптимизация в стандартных компиляторах вряд ли может превратить код в хорошо перемешанный фарш.