Определение размера процедуры на си

Тема в разделе "WASM.ZEN", создана пользователем Android, 2 авг 2006.

  1. Android

    Android New Member

    Публикаций:
    0
    Регистрация:
    24 авг 2003
    Сообщения:
    183
    Адрес:
    Ukraine
    На асме это просто - ставлю метку перед процедурой и после, вычитаю первую из второй.
    Как то же самое можно сделать на си? Сканирование до первого ret не всегда подходит т.к. бывают процедуры с несколькими ret, или часть процедуры находится за ret.
     
  2. nobodyzzz

    nobodyzzz New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2005
    Сообщения:
    475
    допусти у тя такая ситуация
    Код (Text):
    1. int some_func()
    2. {
    3.       .....
    4. }
    5. int some_func2()
    6. {
    7.      ........
    8. }
    тогда sizeof.some_func = some_func2 - some_func, хотя я могу ошибаться
     
  3. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    nobodyzzz
    Обычно так и делают, хотя можно переопределить порядок функций в опциях линкера.
     
  4. ECk

    ECk Member

    Публикаций:
    0
    Регистрация:
    9 апр 2004
    Сообщения:
    454
    Адрес:
    Russia
    Линкер (особенно при оптимизациях) может разместить функции как угодно, то есть может получиться что сперва будет идти some_func2, а за ней уже some_func.
    Как вариант, можно для тех функций, размер которых тебе нужен, создать секцию - и положить обе функции во вновь сделанную секцию (через plagma_alloc(SECTION, some_func)...).
     
  5. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Android
    В си тоже можно делать метки и прыгать на них, следовательно можно взять адрес метки и сделать тоже что и в асме!
     
  6. ECk

    ECk Member

    Публикаций:
    0
    Регистрация:
    9 апр 2004
    Сообщения:
    454
    Адрес:
    Russia
    метками не получится (т.к. метку надо будет размещать вне функции), а если в начале самой функции разместишь метку, она будет недоступна из других функций.
     
  7. KAdot

    KAdot New Member

    Публикаций:
    0
    Регистрация:
    27 фев 2005
    Сообщения:
    38
    делаю так: добавляю в конец функции строку с помощью _asm _emit , ищу ее в памяти, затем адрес_начала_строки - адрес_функции и будет размер
     
  8. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Кстати, для цпп ещё можно отключать оптимизацию директивами до нужного куска и включать её после.
     
  9. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    метку можно разместить и после return. ;)
     
  10. KAdot

    KAdot New Member

    Публикаций:
    0
    Регистрация:
    27 фев 2005
    Сообщения:
    38
    и что это даст?
     
  11. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    аа, да, не внимательно прочитал. вам непонятно как значение метки вытащить из функции. тут без извратов или помощи компилятора не выйдет. Но можно.
     
  12. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    2KAdot
    Наверное так проще всего, только нужно характерные строки вставить, например, в начало функции вставляем
    _asm mov esi, 0ABABABABh
    в конец
    _asm mov esi, 0CDCDCDCDh
    находим разницу, получаем длину с точностью до нескольких байт. Можно оценить более точно путем подъема вверх от первой вставки до первой инструкции функции (это может быть push ebp, например, зависит от компилятора) и спуска вниз до инструкции ret.
     
  13. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Еще один способ. В начало добавляем
    call $+4
    pop esi; esi содержит адрес данной инструкции
    mov [StartOfFunction], esi

    в конец
    call $+4
    pop esi; esi содержит адрес данной инструкции
    sub esi, [StartOfFunction]; получаем длину

    Опять-таки с точностью до нескольких байт.
     
  14. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    только call $+5
     
  15. khv_test

    khv_test New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    135
    если процедура на асм то можно использовать след. код.
    удобно чтоб узнать размер просто вызываем процедуру
    только не надо забывать када ходим скопировать её куданить прибавлять 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
    }
    }
     
  16. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    это можно узнать алгоритмом полного дизассемблирования функции (с запоминанием branch'ей). То, что дерматолог слёзно клянчил по форумам типа ренга. Если без учета тонкостей делать, то это несложный алго -- в ~15-30 строк на С.
    Другой вопрос, зачем это надо. Если компилятор перетасует сами процедуры в коде, это одно, но он может перетасовать и саму процедуру, разбив ее на chunk'и и перемешав с другими процедурами для оптимизации. Тут поможет только такой алго, никакие X - Y и тп тут не прокатят. ;)
     
  17. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    если компиль cl можно так:
    int func_start() { return 1; }
    void func() { ... }
    int func_end() { return 2; }
    ...
    int len = &func_end-&func_start+C; // C = const :)
     
  18. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    правильный ответ - нельзя
    длина блока инструкций в байтах есть понятие лежащее ниже уровнем чем любое понятие языка С
    асм рулез
     
  19. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    _BC_
    Я не встречал уж слишком крутой перетасовки процедур, в лучшем случае вместо вызова какой-то функции в конце процедуры следует jmp на нее, и то этот метод используется редко. Оптимизация в стандартных компиляторах вряд ли может превратить код в хорошо перемешанный фарш.
     
  20. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    z0mailbox
    Никто и не сомневается, что нельзя, народ подсказывает, как это можно было бы сделать.