1. Assembler / Говнокод #13931

    +129

    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
    product:
    .LFB34:
            .cfi_startproc
            xor     eax, eax
            test    esi, esi
            je      .L7
            lea     eax, [rsi-1]
            mov     edi, edi
            add     rax, 1
            imul    rax, rdi
    .L7:
            rep
            ret
            .cfi_endproc

    Оптимизациия умножения через рекурсию. Сишный код:

    inline unsigned long int product_0(const unsigned int a, const unsigned int b, const unsigned long int tmp)
    {
    if (b == 0) return tmp;
    return product_0(a, b-1, tmp+a);
    }

    unsigned long int product(const unsigned int a, const unsigned int b)
    {
    return product_0(a, b, 0);
    }

    Распознать умножение (imul) в этой рекурсивной хрени компилятор смог, но при этом как-то через жопу, нагенерировав при этом много лишнего говна.
    gcc version 4.5.1

    Запостил: j123123, 12 Октября 2013

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

    • > lea eax, [rsi-1]
      > mov edi, edi
      > add rax, 1
      Что-то ему явно нечем было заняться ;)
      Ответить
    • Ответить
      • Вот наглядно видно, что тебя минусуют за дело.
        Ответить
        • Пошел на хуй: тебе наглядно видно?
          Если хочешь общения - зарегай учетку, анальные гости здесь не в почете.
          Ответить
    • > > Оптимизациия умножения через рекурсию. Сишный код:

      > нагенерировав при этом много лишнего говна.

      кто-то написал на С "лишнего говна."

      компилятор не богами писан. он всего лишь компилятор - а не говно-разгребатель. любой оптимизатор можно какой-нибудь глупой херней.
      Ответить
      • >компилятор не богами писан.
        +1
        Авторам компилятора зачет только за то, что он додуплил развернуть эту хвостовую срань в одну инструкцию умножения.
        Ответить
    • Кстати, а если и сложение записать рекурсией?
      Ответить
      • Труъ функциональшина?
        Ответить
        • Мне кажется, Вы немного путаете термины "курение" и "функциональщина".
          Ответить
          • возможно, он имел ввиду "функциональщина головного мозга"
            Ответить
      • Ну, из кода
        unsigned int plus(unsigned int a, unsigned int b)
        {
          if (b == 0) return a;
          return plus (a+1, b-1)
        }


        получается
        mov     eax, edi
        add     eax, esi
        ret


        Хотя можно было бы сделать
        lea     eax, [rsi+rdi]
        ret
        Ответить
        • lea     eax, [rsi+rdi]
          ret
          ;заполнить eax суммой сложения rsi+rdi??
          Но откуда они взялись, в коде ведь только esi и edi?

          Товарищи, прошу прощенья, что не в тему. А как можно на асме поместить результат в переменную?
          Ответить
          • rax это 64 битный регистр, младшей половинкой которого является eax.
            00000000 00000000 000000000 00000000 00000000 00000000 00000000 00000000
            |================================ rax =================================|
                                                 |============= eax ===============|
                                                                   |====== ax =====|
                                                                   |= ah =| |= al =|
            Ответить
            • Ух ты. Спасибо, кэп!
              Схему Вашу сохраню, на всякий случай.
              Ответить
          • > А как можно на асме поместить результат в переменную?
            Ну в интелосинтаксисе так:
            mov variable, eax
            Ответить
            • Святая простота. А я так делал:
              push variable
              pop eax (или наоборот, это теперь уже не суть важно). Теперь буду делать так.
              Спасибо!
              Ответить
              • var
                  i:integer;
                begin
                  asm
                    xor edi,edi
                    xor esi,esi
                    mov esi,20
                    mov edi,20
                    imul edi,esi
                    mov i,edi
                  end;
                  showmessage(inttostr(i))
                end;

                :D
                Ответить
                • Мне все больше и больше нравится асм. Шикарный язык, даже безо всяких макросов и без invoke (передавать параметры в стек через push).
                  Клсссно на нем API дергать.
                  Ответить
                  • А в других языках как дергать неосилил?
                    Ответить
                    • Я уже писал, что мне относительно легко учить языки, потому, что я знаю API и умею их вызывать.
                      Ответить
                      • при этом ты не можешь слезть с делфи
                        Ответить
                        • Я не профессиональный программист, и пишу относительно простые проги и то в случае необходимости. Для меня нет смысла учить с++ и подобные ему языки, только ради того, чтобы в программе все было "по-взрослому" и ебать себе мозг с MFC и утечками памяти. В дельфе меня все устраивает. Форма готовая, компоненты готовые, есть поддержка скинов. Более того, даже после базового изучения Делфи мне стало намного легче и понятнее работать с другими языками.
                          Ответить
                          • Я тоже не профессиональный программист - я студент пока. И Плюсы учить тоже не собираюсь. Но я интересуюсь всяким. Технологиями, языками, методологиями. Я не завис на одном шарпе - я сейчас изучаю ruby, изучаю функциональщину, в матан повторно вчитываюсь. Секешь?
                            На мой взгляд Делфи неудобен. Попробуй другие языки. Из того, что я пробовал самый удобный руби.
                            Ответить
                            • Может, обменяемся опытом?
                              Ответить
                              • Кстати, Delphi - самое простое, что только может быть в программировании. Но это
                                не значит, что его нужно учить поверхностно. Халявы в изучении программирования
                                вообще нет. Ты очевидно имеешь именно поверхностные знания о Delphi,
                                поэтому судишь так. Между тем я тебя хорошо понимаю, я тоже раньше до
                                тошноты ненавидел паскальный синтаксис, меня бы никто не заставил
                                читать исходники. Но когда я ухлопал больше 2 лет на разработку проекта
                                на удобном и хваленом PureBasic и не получил ожидаемых результатов -
                                понял, что проиграл и изрядно свалял дурака, связавшись с этим языком и что он непригоден для разработки сколько-нибудь серьезных программ.
                                Пришлось срочно учить что-то более серьезное. Все остальные компиляторы
                                (сишный билдер, Autoit,purebasic и тп.) уже давно покрылись пылью, я их
                                даже не открываю.
                                Ответить
                                • >хваленом PureBasic

                                  Кем хваленым?) От него даже MS открестились) Pure C - язык для очень специфичных задач. Например мне он интересен чисто в академическом смысле, не думаю, что буду на нем писать. Плюсы излишне сложны - не то, что бы я не смог их выучить, просто я не вижу смысла убивать на них столько времени.
                                  Ответить
                                  • >>От него даже MS открестились)

                                    http://purebasic.com/
                                    Ничего не путаешь?
                                    Ответить
                                    • Я подумал, что pureBasic - это чистый бейсик. С их стороны было очень не по божески называть диалект Pure ) Не знаком, но знаком с бейсиком вообще. Ну и хорошего сказать не могу
                                      Ответить
                                      • Вот что мне ответил один умный человек, когда я дал ему ссылку и спросил, стоит ли учить этот язык:
                                        -Хромой аналог Visual Basic на костялых.
                                        Я тогда пропустил это мимо ушей. Зря, как оказалось.

                                        И вообще, простота, как говорится, хуже гомосексуализма.
                                        Ответить
                                        • Почему же? Python - очень простой язык. Что не мешает ему быть универсальным.

                                          MS сами отказались от VB. Фактически Бейсик существует в .NET, но на самом деле это тот же шарп с синтаксисом бейсика. А бейсик мертв
                                          Ответить
                                          • >>А бейсик мертв

                                            Какая безвременная смерть. Всего-то сорок с лишним лет...

                                            keep it short and simple!
                                            sincerely yours, cap.
                                            Ответить
                                        • Keep It Simple, Stupid
                                          Ответить
                • >xor edi,edi
                  >xor esi,esi
                  Нет никакого смысла занулять регистры перед тем, как в них записывать какие-нибудь числа
                  Ответить
                  • Впредь буду знать, спасибо.

                    А как занести в регистр указатель на строку??
                    Ответить
                    • Не знаю как там это делается в паскалевых асмовставках, но в GCC асмовставках с AT&T синтаксисом это делается примерно так:
                      char msg[] = "Some text";
                        asm volatile (
                        "mov %0, %%rsi\n\t"  // msg
                        "...еще какая-нибудь фигня на ассемблере."
                        :
                        : "g" (msg)
                        : "%rsi"
                        );

                      Подобной фигней я в свое время занимался, когда захотел написать хелловорд на асмовставках под GNU/Linux
                      https://www.linux.org.ru/forum/development/8780935
                      Ответить
                      • какой кошмар.
                        Ответить
                        • Минусуйте теперь хоть до потери пульса, мать вашу.
                          Я скрыл все плюсы и минусы.

                          От меня теперь не ждите плюсов, буду благдарить на словах.
                          Ответить
                        • не нравится - код в машинном
                          Ответить
                          • Чего ты мелочишься, тогда уже лучше вручную сектора магнетизировать.
                            Ответить
                            • Это ты у нас глобализируешь. Тебе ассемблер ну нафиг не сдался.
                              Ответить
                              • Асм + Delphi => сила
                                Ответить
                                • Асм + Delphi - сила = ?
                                  Ответить
                                  • асм + delphi - сила= kegdan / 1024
                                    )
                                    Ответить
                                    • Да пребудет с тобой (асм + delphi - kegdan / 1024)!
                                      Ответить
                                      • Ответить
                                      • 1024, на ноль не делят.
                                        Да пребудет с тобой (асм + delphi - kegdan / (1024+1))
                                        Ответить
                                        • > на ноль не делят
                                          На ноль можно делить. Получится +∞ или -∞ в зависимости от знака ;)

                                          Нельзя делить только 0 на 0.
                                          Ответить
                                          • Последователь Галуа?

                                            Кегдан, ты не тролль, а просто детонатор флуда. Наказать онально, мой вердикт.
                                            Ответить
                                            • > Последователь Галуа?
                                              А вот в полях Галуа, насколько помню, делить на ноль как раз таки нельзя...
                                              Ответить
                                          • > Нельзя делить только 0 на 0.
                                            Используйте питательную смесь NaN.

                                            Смесь NaN. И Ваша программа не падает!
                                            Ответить
                                          • На ноль делить нельзя. на бесконечно малую - можно
                                            Ответить
                                            • Вопрос в том, какого типа операнды. Целочисленные - нельзя, числа с плавающей точкой - можно делить что угодно на что угодно.
                                              Ответить
                                              • не путай матан с устроиством компьютера
                                                Ответить
                                                • Исключения ты не получишь, просто получишь в качестве результата не-числа.
                                                  Ответить
                                        • Т.е. 1024 == 0? Что ещё нового о математике я сегодня узнаю?

                                          P.S. А производители жёстких дисков-то не обманывают нас, когда умножают на 1000.
                                          Ответить
                            • Зачем вручную, если можно бабочками? xkcd #378
                              Ответить
                      • > "mov %0, %%rsi\n\t"
                        Ня! ^_^
                        Ответить
    • >unsigned long
      Не поможет.
      Ответить
    • goo.gl/rVJoRW
      так сойдет?
      Ответить
      • http://goo.gl/QwZuyh
        Если оба числа переменные, он еще вставит проверку на ноль, так что неидеально
        Ответить
    • add rax,1? А комманды inc/dec уже не в тренде?
      Ответить
      • Сравнив скорость
        xor     eax, eax
        rep:
        inc     eax
        jnz     rep

        и скорость
        xor     eax, eax
        rep:
        add     eax, 1
        jnz     rep

        Разницы на своем процессоре Intel Core2 Quad Q9300 я не заметил
        Ответить
        • Да там оно может быть как-то по-разному влияет на загрузку подсистем проца, и на таких простых примерах это не увидеть...

          А может быть совет про то, что стоит юзать полные инструкции вместо сокращенных inc, lodsb, jcxz и т.п. уже устарел, и они выполняются с той же скоростью...

          P.S. А вот по поводу длины команд есть стопроцентная инфа: мельчить нельзя. Декодеры справляются только с фиксированным числом команд в блоке (что-то вроде 6 команд на 16 байт, и вроде были еще и ограничения на тип этих команд), и если не соблюдать это соотношение, то команды будут декодироваться медленнее из-за простоя декодеров.
          Ответить
          • >мельчить нельзя
            Нужно по возможности брать крупные команды?
            Ответить
            • http://www.intel.com/content/dam/doc/manual/64-ia-32-architectures-optimization-manual.pdf

              Правила про крупные команды я не нашел, наверное моя инфа устарела, или вообще была брехней... Но правил по подстройке кода под декодеры там куча (страница 147 и ниже).
              Ответить
        • Assembly/Compiler Coding Rule 33. (M impact, H generality)
          Чук и ГекINC and DEC
          instructions should be replaced with ADD or SUB instructions, because ADD and
          SUB overwrite all flags, whereas INC and DEC do not, therefore creating false
          dependencies on earlier instructions that set the flags.
          Ответить

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