Ассемблер, прощай!

Дружок, если ты соблюдаешь верность ассемблеру, а не пишешь на си – эта статья для тебя.

Почему мы пишем только на асме?

Когда-то давно это было вполне допустимо и считалось признаком мастерства. Во времена 32-битных систем это было вполне оправданно, но с приходом 64-битных, ассемблерщикам пришлось не сладко.

Разумеется, основные опкоды просто расширили DWORD до QWORD и стали занимать места на 4 байта больше. В 64-битном мире больше не нужны релоки, все относительные адреса помещаются в 4 байта!

Я постараюсь перечислить основные преимущества Си: как оказалось есть множество людей, которые не могут пересесть на новую лошадку, в силу страха неизвестного или предубеждений.

  1. Легкая компиляция как в 32 так и 64 битных файлов. Зачастую достаточно просто переключить режим сборки и если код написан правильно, он будет одинаково хорошо работать и там и там. Единственное ограничение – ассемблерные вставки, для 64 битных сборок их надо делать в отдельном файле.
  2. Больше хидеров. Каждый кто писал на асме знает – перегонять хидеры из msdn – неизбежное зло. На си они поставляются вместе с sdk или даже visual studio.
  3. Больше исходников. В силу того, что написав приложение используя только стандартную библиотеку си – оно будет кросплатформенно, исходников на си огромное множество. Больше не придется выдирать бинарные куски или переписывать алгоритмы с других языков.
  4. Классы, у Си с плюсами есть эта классная фишка. Они могут казаться чем-то подозрительным, но когда вы посмотрите как они выглядят в ассемблированном виде вы успокоитесь. Классы абсолютно не избыточны и не тормозят работу программы, но ускоряют разработку и облегчают понимание кода.
  5. Оптимизация. Коронная фишка ассемблера. Времена ms-dos давно прошли, никто не заметит лишнюю пару сотен процессорных тактов, да и ключи оптимизации компилятора позволят сильно срезать углы! На хабре обсуждалось какие ключи дают лучшую производительность, но скажу по секрету, что лучшую производительность даёт лучший алгоритм.
  6. Дебаг. Снова ставить int3 и ловить исключение в Olly? Нет, отладка в VisualStudio позволяет идти прямо по сишному коду, заглядывая в значение переменных, раскрывая вложенные структуры и даже подсматривая ассемблерный код!
  7. Скорость. Всё вышеизложенное приводит к ускорению рабочего цикла, от задумки до релиза. Ты думаешь о действительно важных вещах, а не о том какой выбрать регистр.

Он обещал вернуться

Разумеется, нельзя отказаться от ассемблера совсем, есть ряд задач где он просто необходим. Если вы его не знаете, то изучите, для малварщика это обязательное условие. Я лишь призываю использовать инструменты адекватные задаче и современным реалиям.

История

Для меня решающим фактором для перехода на Си и плюсы в частности послужил класс Cmem, который избавил меня от головной боли по поводу утечки памяти. Деструктор (функция вызываемая при выходе из области видимости экземпляра класса, по сути перед ret в функции) – освобождал мою память неявно и автоматически, чем полностью покорил моё сердце…

P/S Если вы тоже прошли долгий путь от “Пишу всё на ассемблере” до “Пересел на си”, расскажите о нём в комментариях!

15 thoughts on “Ассемблер, прощай!

  1. > Классы абсолютно не избыточны и не тормозят работу программы, но ускоряют разработку и облегчают понимание кода.
    Я бы тут поспорил, сам класс действительно не избыточен, ровно до того момента, пока не началось тру-ооп

    1. Абстракции(“тру-ооп”) строятся ради упрощения описания бизнес логики приложения, где обычно на ура справляются даже интерпретируемые языки. Конечно же, никто в здравом уме не имплементит чувствительные к перформансу вещи, используя большой уровень абстракции. “Зачем стрелять себе ногу ?”. С другой же стороны, зачем писать неудобный процедурный код, когда это не дает никаких преимуществ. “Преждевременная оптимизация — корень всех зол”. Выиграв чуть чуть перформанса из-за того что ты заимплементил логику приложения на низком уровне, можно столкнутся с тем что последующая поддержка и расширение функционала может стать очень сложной задачей.

      P.S. Процедурный стиль программирования уместен только для каких то утилитных вещей.

        1. Да, я и указал, процедурный стиль и низкоуровневое программирования уместно только для утилилитного софта(системный софт == утилитный софт, сам по себе он не живет). Ну и в случаях где без этого никак не обойтись.

          P.S. В статье не было сказано что автор имеет ввиду написание именно системного софта, там говорилось о написании ПО в принципе. А учитывая специфику данного ресурса, имелось ввиду написание малвари. А малварь в большей своей части не является системным софтом, а лишь использует его.

          1. >Да, я и указал, процедурный стиль и низкоуровневое программирования уместно только для утилилитного софта(системный софт == утилитный софт, сам по себе он не живет). Ну и в случаях где без этого никак не обойтись.
            Простите, я не знаю что такое “процедурный стиль”, “утилитный софт”, стараюст не забивать голову книжными терминами.

            > В статье не было сказано что автор имеет ввиду написание именно системного софта
            Я думаю это и так очевидно, асм системный язык

            > А малварь в большей своей части не является системным софтом, а лишь использует его.
            Ну вы видимо большой эксперт в этом, если позволяете себе такие обобщения

            1. > Ну вы видимо большой эксперт в этом, если позволяете себе такие обобщения.
              Нет, никогда не считал себя и не являлся экспертом в области малвари.

              К современной малвари нельзя относится как к системному софту, так как зачастую это клиентская часть клиент серверного приложения, в ней есть своя модель, сервисы, контроллеры.

              https://en.wikipedia.org/wiki/System_software
              Цитата: System software (systems software) is computer software designed to provide services to other software.

              Конечно же, в малвари часто используются сервисы, которые напрямую работают с системой. Но, если мы говорим о малвари как о полноценном, самодостаточном приложении, у которого есть своя логика, то малварь не является системным софтом, она его лишь использует. По этому использование ООП при дизайне малвари не так уж и плохо.

              >Я думаю это и так очевидно, асм системный язык
              Да, в узких системных сервисах без него не обойтись, но еще раз повторюсь, писать всю логику приложения(в данном случае, малвари), на языке низкого уровня, не очень рационально.

              По поводу процедурного стиля(стиль написания который использовался во времена популярности C и Pascal):
              Это больше не стиль, а способ мышления, в котором код пишется так, как будет выполнятся, в смысле “шаг за шагом”. Чаще всего им страдают разработчики очень долго разрабатывающие на языках низкого уровня(таких как C и Pascal). Основная его проблема в том , что код пишется с недостаточным уровнем абстракции, что может повлиять на его дальнейшую поддержку и разработку.

              1. К чему этот разговор? Вы предлагаете юзать ооп? Окей, но для системных задачь оно может быть избыточно, не думайте что я не пишу ооп код. Для примера как-то недавно писал ассинхронный прокси сервер с TLS на бусте(тру-ооп), всё ок, красиво и понятно, плюшки ввиде параметризированных коллбеков – класс. Но производительность говно, как бы я её не пытался выжать. Переписал на голый IOCP, так у меня при стресс-тестах винда подвисала только от того что оно очь быстро освобождало ресурсы (30к соккетов за 7-10 сек).

                Пожалуйста если вы пилите софт – юзайте ооп, это норм, но разговор же про системный язык, я думаю асм во основном используется для специфических задачь

                > Основная его проблема в том , что код пишется с недостаточным уровнем абстракции, что может повлиять на его дальнейшую поддержку и разработку.

                Не хочу развивать антагонизм, но основная проблема тру-ооп разработчика, что витая в облаках плюшек управляемых языков, рано или поздно наступает деградация понимания принципов работы ПК и ОС. А зачем об этом думать, если это не наши проги тормозят, а ваш четырёхядерный проц слишком слабый. Если вы думаете что недостаточный уровень абстракции усложняят понимание то вы заблуждаетесь. Мне к примеру не составит труда понять системный код, будь он написан на С, Delphi или это листинг дизассемблера. Другое дело что код может быть написан не качественно, но эта проблемма актуальна для всех языков. Моё мнение которого я придерживаюсь последнее время это: нахер эти парадигмы, есть задача и есть оптимальные способы решения, если парадигма стоит в разрез со здравым смыслом, то жертвуем парадигмой во имя здравого смысла. Если ваше ооп такое простое в понимание, то какого хрена появляются такие вещи как рефлексия, видимо не от хорошей жизни 🙂

                1. ООП и юзается, чтобы избавить разработчика от таких низкоуровневых знаний или работа с памятью (ее выделение, освобождение и прочее), которые часто просто мешают.
                  >Не хочу развивать антагонизм, но основная проблема тру-ооп разработчика, что витая в облаках плюшек управляемых языков, рано или поздно наступает деградация понимания принципов работы ПК и ОС. А зачем об этом думать, если это не наши проги тормозят, а ваш четырёхядерный проц слишком слабый.

                  человеческие ресурсы и время гораздо дороже машинного, поэтому обновите свою пекарню.

                  >то какого хрена появляются такие вещи как рефлексия, видимо не от хорошей жизни
                  если они появились, то значит несут в себе какой-то смысл и предоставляют инструмент решения чего-то.
                  >Переписал на голый IOCP
                  Зато теперь строго привязаны к одной ос и получили непереносимый софт

                  1. > человеческие ресурсы и время гораздо дороже машинного, поэтому обновите свою пекарню.

                    Существует разница в уровне ответственности за неверный диагноз между доктором в доврачебном кабинете и доктором в операционной. Если один за сутки лечит 100 насморков, то другой вырезает 1-2 опухоли. Так что стоимость вашего труда зависит не только от времени.

                    > ООП и юзается, чтобы избавить разработчика от таких низкоуровневых знаний или работа с памятью (ее выделение, освобождение и прочее), которые часто просто мешают.
                    > если они появились, то значит несут в себе какой-то смысл и предоставляют инструмент решения чего-то.
                    > Зато теперь строго привязаны к одной ос и получили непереносимый софт

                    Спасибо КЭП 🙂

  2. Это всё верно для простого кода. Ничего серьёзного студией не отладить, так же как и от оптимизации на уровне манипуляций парой регистров толку ноль.

  3. Имхо, автору надо было назвать статью “Ассемблер, в нужное время и в нужном месте”, в кодинге, как и везде работает правило 20\80. Оптимизация 20% кода дает 80% прирост производительности. Любые высокоуровневые ЯП это как безопасная бритва, тогда как асм это бритва опасная) Её еще правильно заточить нужно.

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