Задать вопрос
@blecked88

Как корректно вывести функцию в байтовом виде?

Хочу реализовать нечто такое:

#include <stdio.h>
#include <stdint.h>

typedef unsigned char uchar;

int f(int a, int b) {
    return a + b;
}
void _end(void) {};


int main(void) {
    uchar* start = f, *end = _end;
    int size = (int)(end - start);
    printf("size = %i\n", size);
    for (int i = 0; i < size; ++i) {
        printf("%02X ", *(start + i));
    }

    return 0;
}


однако данная программа либо вообще ничего не выдает (size < 0), либо выдает какие то неотносящиеся к данной функции байты.

реализовать надо так, чтобы работало на ЛЮБОМ компиляторе. Как это можно сделать?
  • Вопрос задан
  • 70 просмотров
Подписаться 1 Средний 4 комментария
Пригласить эксперта
Ответы на вопрос 5
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Переписать всё на ассемблер.
Компилятор C/C++ может использовать оптимизацию, менять порядок функций, делать функции инлайновыми.
Ответ написан
AshBlade
@AshBlade
Просто хочу быть счастливым
Я назвал 2 функцию не _end, а g и сработало. Возможно, gcc как-то по особенному интерпретирует это название - при дизассемблировании функции _end, даже не было.

Но тебе уже сказали, что компилятор может сделать все, что угодно и гарантировать расположение/вид функций нельзя.
Ответ написан
Комментировать
15432
@15432
Системный программист ^_^
Ну почему же ничего не выдает, size < 0 означает, что функция _end расположена перед функцией f, и это нормально, потому что часто компилятор соблюдает алфавитный порядок.
Назовите их func_a и func_b и попробуйте ещё раз. Обязательно используйте в коде эти функции, чтобы они не оказались вырезанными
Ответ написан
Комментировать
@res2001
Developer, ex-admin
Что мешает предусмотреть варианты когда f < _end и f > _end?
https://godbolt.org/z/8M33E4PYo
Но это не гарантирует, что компилятор чего-нибудь не вставит между функциями. О чем и говорит итоговый выхлоп.
И еще выхлоп может быть разным при разных флагах оптимизации: -O0/1/2
Ответ написан
Комментировать
mayton2019
@mayton2019
Bigdata Engineer
Это так не работает. Тут есть квантовый эффект что если ты подглядываешь за кодом
то он ведет себя так. А если уберешь эту формулу расчета длины то код будет собран
совсем другой.

int f(int a, int b) {
    return a + b;
}
void _end(void) {};


Может быть будет инлайнинг функции f. Поэтому расчет длины кода тебе практически
не несет никакой информации. Тоесть никаких выводов из его длины сделать нельзя.

И трюки которые работали в ассемблере могут не работать для языков где есть агрессивная
оптимизация.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы