1. C++ / Говнокод #24474

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    #include <stdio.h>
    #include <stdlib.h>
    #include <inttypes.h>
    
    void test1(void)
    {
      printf("test1\n");
    }
    void test2(void)
    {
      printf("test2\n");
    }
    void test3(void)
    {
      printf("test3\n");
    }
    void test4(void)
    {
      printf("test4\n");
    }
    
    uint8_t func_dist[3] = {(uint8_t)((char *)test2-(char *)test1), (uint8_t)((char *)test3-(char *)test2), (uint8_t)((char *)test4-(char *)test3)};
    
    void callf(uint8_t fn)
    {
      size_t sum_dis = 0;
      for (uint8_t i = 0; i < fn; i++)
      {
        sum_dis += func_dist[i];
      }
      ( (void(*)(void)) ((char *)test1+sum_dis) )  ();
    }
    
    int main(void)
    {
      callf(0);
      callf(1);
      callf(2);
      callf(3);
      return EXIT_SUCCESS;
    }

    Зожатие указателей. Главное чтоб длины функций не превышали 255 и чтоб функции шли строго подряд, как они объявлены кода
    Как сделать чтобы это компилировалось сишкой?

    Запостил: j123123, 10 Июля 2018

    Комментарии (12) RSS

    • https://godbolt.org/g/8pmgBp и вообще, почему uint8_t func_dist[3] не инициализируется в компилтайме? Говно какое-то, не могли как в ассемлере сделать.

      _GLOBAL__sub_I_test1():
              mov     eax, OFFSET FLAT:test2()
              sub     rax, OFFSET FLAT:test1()
              mov     BYTE PTR func_dist[rip], al
              mov     eax, OFFSET FLAT:test3()
              sub     rax, OFFSET FLAT:test2()
              mov     BYTE PTR func_dist[rip+1], al
              mov     eax, OFFSET FLAT:test4()
              sub     rax, OFFSET FLAT:test3()
              mov     BYTE PTR func_dist[rip+2], al
              ret
      func_dist:
              .zero   3
      Ответить
    • показать все, что скрытоvanished
      Ответить
      • длина функций это то, сколько эта самая функция занимает байт в исполняемом сегменте
        Ответить
        • Entry pointy в Вашу шарагу не завезли?
          Ответить
          • у меня в шараге-то и курса программирования не было толком. По образованию я химик-теоретик
            Ответить
    • где тут плюсы?
      Ответить
      • а ты попробуй собери это сишкой
        Ответить
        • А в чём проблема?
          Ответить
          • Выражение (uint8_t)((char *)function1 - (char *)function2) в компилтайме не считается, а вставлять рантаймовую питушню, как это происходит в плюсах, сишка не умеет.
            Ответить
    • вообще, с точки зрения C и C++, выражение вида
      uint8_t ptrdif = (uint8_t)((char *)function1 - (char *)function2);

      не может быть вычислено на этапе компиляции. Компилятор узнает о расстоянии между двумя указателями на фукцнями уже в конце, когда все оттранслировано в машинный код.
      Вот типа будет у нас в некоторой функции function3 код:
      if ( (uint8_t)((char *)function1 - (char *)function2) == 20 ) {делай_некую_фигню;}

      Если разница между function1 и function2 будет равна 20 то нужно всегда выполнять {делай_некую_фигню;} и проверка условия лишняя, т.к. указатели на функции в процессе выполнения не могут сместиться. Саму проверку if() можно выкинуть
      Если разница между function1 и function2 будет не равна 20, никогда ничего выполнять не надо и проверку делать тоже смысла нет.
      Но тут интересный момент. Если компилятор сделат те или иные действия (выкинет только if() проверку т.к. решит что там всегда true или выкинет и проверку и код т.к. решит то там всегда false) - это может в итоге повлиять на расстояние между двумя указателями, и получится что эта оптимизация неправильная.
      Вот потому-то Настоящие Цари не будут использовать какие-то анскильные плюсы и сишку, а будут писать сразу в машинных кодах или в крайнем случае на ассемблере
      Ответить
    • > сишкой
      Добавить новый формат релокации -- расстояние между джвумя символами. Ну или возможность инициализации глобалок в рантайме как в крестах.

      З.Ы. Дизасм не глядел, так что могу заблуждаться.
      Ответить

    Добавить комментарий