Как стать автором
Обновить
98.92

Assembler *

Язык программирования низкого уровня

Сначала показывать
Порог рейтинга
Уровень сложности

Любителям x86-64 assembler посвящается: DIY волокна в C++

Уровень сложностиСложный
Время на прочтение26 мин
Количество просмотров10K

Нас ждёт мозговыносящая смесь 64/32-битного ассемблера и старого-доброго C++. Мы сделаем собственную реализацию... Волокон (fibers) без вызова Win API и звонков в службу спасения.

Читать далее

Новости

Решение задачи с Route 256 на goalng

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров1.9K

В этой статье разбирается решение задачи «Гистограммы» с контеста Route 256 от Ozon с помощью SIMD.

Условие задачи

Гистограммой является массив, каждый элемент которого указывает высоту столбика на соответствующей позиции. Две гистограммы считаются совпадающими, если при совмещении одной гистограммы с другой гистограммой, повёрнутой на угол 180°, получается ровный прямоугольник без наложений и пропусков.

Читать далее

Низкоуровневое программирование под 8086 для любопытных, часть 2

Уровень сложностиСредний
Время на прочтение15 мин
Количество просмотров9K

В этой части нас ждёт погружение в один из способов организации мультипоточности на базе единственного ядра процессора. Мы научимся принудительно переключать выполнение между полностью зацикленными участками кода, ничего не "знающими" о каком-то другом коде, конкурирующем за процессорное внимание. По ходу повествования будут даны все необходимые пояснения и читателю не придётся обращаться к другим источникам, кроме первой части статьи.

Читать далее

Часть 3. Векторизация на Go: CGo, транзакции, компиляторы, поддержка, байтовые инструкции

Время на прочтение8 мин
Количество просмотров2K

В первой части статьи мы рассмотрели, как можно вручную ускорить Go-код с помощью векторизации и SIMD-инструкций, реализованных через Go-ассемблер. Написали простую, но показательно быструю реализацию sliceContains и увидели, что даже базовая векторизация может дать ускорение в 10–14 раз по сравнению со стандартной реализацией.

Во второй части статьи погрузились в практическое применение SIMD в Go-ассемблере, реализовали функцию SliceContainsV1 и изучили, как с помощью VADD, VDUP и других инструкций можно добиться 10–14-кратного ускорения простых задач.

Но возможности оптимизации Go-программ на этом не заканчиваются. В этой части мы пойдём дальше: рассмотрим другие техники низкоуровневой оптимизации — от использования C-кода и альтернативных компиляторов с поддержкой векторизации до работы с аппаратными транзакциями памяти на Intel. Поговорим о том, как внедрять ассемблер в продакшен-код, не боясь за его поддержку, и как обойти ограничения стандартного Go-компилятора.

Привет, Хабр! Меня зовут Игорь Панасюк, я работаю в Яндекс, преподаю в ИТМО, а также в свободное время выступаю на конференциях, делюсь опытом в соцсетях и помогаю развитию Go-сообщества, веду телеграм-канал и youtube-канал. Если вы уже знакомы с базовыми техниками векторизации, эта часть поможет глубже понять, как устроены продвинутые способы ускорения Go-кода и на что стоит обратить внимание при работе с архитектурно-зависимыми оптимизациями.

Читать далее

Часть 2. Векторизация и SIMD в Go: ускорение поиска и сравнения в массивах

Время на прочтение10 мин
Количество просмотров2K

Ускорить простые задачи, вроде поиска в массиве и сравнения слайсов, поможет мощь SIMD. Эти векторные инструкции, которые обрабатывают десятки байт данных за один такт процессора, отличная замена традиционным циклам. Во второй части статьи мы погружаемся глубже в практическое применение SIMD в Go-ассемблере, реализуем функцию SliceContainsV1 и изучим, как с помощью VADD, VDUP и других инструкций можно добиться 10–14-кратного ускорения простых задач.

Из этой статьи вы узнаете:

Как устроено сравнение массивов с помощью SIMD-инструкций;

Почему векторизация быстрее бинарного поиска;

Как правильно работать с регистрами, фреймами и указателями в Go-ассемблере;

Что нужно учесть при переносимости и поддержке низкоуровневого кода;

Когда ассемблер оправдан и безопасен в реальных проектах на Go.

Информация будет актуальна как разработчикам, оптимизирующим критически важный код, так и тем, кто хочет глубже понять архитектуру выполнения и взаимодействие с «железом».

В первой части статьи мы разобрали саму идею ускорения кода на Go с помощью ассемблера. А в этой разберём её практическое применение.

Читать далее

Зачем программисту дизассемблер в 2025: отладка на слепую под редкие MCU

Уровень сложностиСложный
Время на прочтение3 мин
Количество просмотров1.7K

Даже в 2025 году, когда вокруг нейросети, автогенерация кода и IDE с предиктивным интеллектом, работа с редкими микроконтроллерами всё ещё может обернуться настоящим хардкором. Особенно, если речь идёт о «слепой» отладке без отладчика, когда в арсенале только прошивка, HEX-файл и пара байтов на выводе. В этой статье — личный опыт, много хардкора, дизассемблирование вручную и поиск глюка в 2 КБ бинаря.

Когда говорят «отладка», в 2025 году чаще всего имеют в виду жмяк на F5 в Visual Studio Code или лог с CI/CD. Но в embedded-мире, особенно если ты копаешься в системах с 8-битным контроллером 2006 года выпуска, это слово может означать кое-что пострашнее. Например — «прошивка вылетает на 4-й секунде, данных в UART нет, отладочного интерфейса нет, документации почти нет, а заказчик просит сделать "как раньше работало"». И вот тут начинается старый добрый reverse engineering.

Читать далее

Часть 1. Почему Go-ассемблер и векторизация могут быть полезны: идея для ускорения

Время на прочтение12 мин
Количество просмотров5.3K

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

Ассемблер может показаться сложным и пугающим, но он открывает большие возможности для работы с низкоуровневыми оптимизациями. Готовы разобраться, как это работает? Тогда погнали!

Привет, Хабр! Меня зовут Игорь Панасюк, я работаю в Яндекс, преподаю в ИТМО, а также в свободное время выступаю на конференциях, делюсь опытом в соцсетях и помогаю развитию Go-сообщества.

Читать далее

Реализация алгоритма PolyUnpack для распаковки вредоносного ПО

Время на прочтение9 мин
Количество просмотров781

Одним днём я читал отчёты по TI из различных источников. В одном из таких отчётов упоминался некий алгоритм для распаковки вредоносного ПО, под названием PolyUnpack. Мне стало интересно, и я решил изучить данную тему. Оказалось, что в Интернете очень мало информации по данному алгоритму. Из интересного я нашёл статью, в которой впервые был описан алгоритм и чью-то курсовую работу.

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

Читать далее

Низкоуровневое программирование под 8086 для любопытных, часть 1

Уровень сложностиСредний
Время на прочтение27 мин
Количество просмотров10K

Вторая часть уже здесь.

В первой части мы:

посмотрим, как работать с памятью и регистрами 8086

узнаем, как написать простую программу на ассемблере прямо в отладчике

изучим работу механизма прерываний и сделаем демонстрационный пример

Статья рассчитана на тех, кто имеет начальный опыт программирования, но хочет понять основы низкоуровневого программирования и многозадачности.

Примеры в бинарном виде доступны по ссылке

Читать далее

RISC-V: векторное расширение и алгоритм Витерби

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров2.3K

Недавняя публикация о векторном расширении RISC-V архитектуры, подтолкнула меня к мысли написать небольшую заметку об использовании данного расширения в задаче, имеющей практическое применение. После появления векторного расширения, в сети начали публиковаться статьи о применении RISC-V ядер с данным расширением в задачах, ранее в которых безальтернативно использовались только процессоры ЦОС. В данной статье рассматривается тест, в котором используется алгоритм декодирования Витерби - задача, требующая значительных вычислительных ресурсов.

Читать далее

Упражнение на ассемблер 8051 для LLM — или «игра в испорченный компилятор»

Время на прочтение5 мин
Количество просмотров2.3K

В очередной дискуссии о вреде и пользе новомодных "искусственных интеллектов" (или как точнее их называют LLM) в программировании, пришёл на ум такой простой эксперимент, который я приглашаю повторить всех желающих с разными вариациями.

Возьмём очень простую задачу - скомпилировать код. Для наиболее однозначного соответствия я беру код на ассемблере - и хочу получить HEX-файл. Это задача которую можно выполнить на бумажке (имея под рукой список команд и помня формат файла) - да в древние времена кому-то и приходилось такую "ручную компиляцию" выполнять. А что нам ответит, например DeepSeek?

Цель не в том чтобы снова поиронизировать над пропонентами LLM, а просто показать как кажущаяся "логика умозаключений" LLM не выстраивается в цепочку, иными словами рвётся от утверждения к утверждению. Думал также, что пример также может служить подспорьем в общении с менеджерами требующими бурного внедрения ИИ в разработку - но возможно он слишком технический.

Итак, заработает ли сгенерённый код?

Метод Монте-Карло в алгоритме обратного распространения ошибок с параллельными вычислениями

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров7.4K

Был проведён эксперимент для проверки, можно ли существенно уменьшить объём вычислений в алгоритме обратного распространения ошибок с параллельными вычислениями за счёт использования на каждом шаге обучения только части обучающих образцов, выбранных случайным образом, а также определение того, какой выигрыш по времени даст использование языка Ассемблера в самых внутренних циклах (в программе, написанной на языке C++).

За основу был взят классический персептрон и алгоритм обратного распространения ошибок, основанный на методе градиента, который объяснялся на курсе Mashine Learning Стэнфордского университета. Он был доработан, чтобы можно было использовать параллельные вычисления. Была написана программа на языке C++ для Linux, её функции (создание, обучение нейронной сети, распознавание данных, закачка больших файлов на сервер и т. п.) вызываются из программ, написанных на любых языках программирования, по протоколу Socket.

Для параллельных вычислений создаётся ntheads объектов нейронной сети, где ntheads — количество потоков (процессоров), в которые записываются части большого массива обучающих образцов, и на каждом шаге алгоритма обратного распространения ошибок совершается прямое и обратное распространение для каждого образца, имеющегося у объекта нейронной сети. Вычисления для каждого объекта производятся в отдельном потоке. Результатом этих вычислений являются суммарные градиенты слоёв сети каждого объекта, они суммируются друг с другом, и полученные градиенты используются для модификации матриц весов нейронной сети, которые затем прописываются во все слои сети объектов нейронной сети.

Читать далее

Термочувствительные кварцевые резонаторы: must have или must die?

Уровень сложностиСредний
Время на прочтение18 мин
Количество просмотров5.7K


Парадоксально, но факт: у термочувствительного кварцевого резонатора РКТ-206 зарубежных аналогов можно считать, что не существует (даже буквы в наименовании кириллические). Западными (точнее восточными, так как речь идет про Seiko-Epson), как их модно стало называть, «партнерами» выпускались аналогичные термочувствительные кварцы, даже с похожим названием HTS-206. Но сейчас, как можете сами убедиться по этой ссылке, их выпуск прекращен «из-за уменьшения объема продаж». Изобилие, представленное на картинке (встреченной в английской Википедии), давно уже сошло на нет. Вроде бы кто-то из европейцев все еще выпускает термокварцы на частоты около 5 МГц, но на данный момент мне их разыскать не удалось.

В статье мы попробуем сначала разобраться, в чем достоинства и недостатки кварцевых датчиков температуры сравнительно с другими способами, а затем предпримем попытку построить датчик на основе термочувствительного кварца. Это все еще может быть практически целесообразным занятием, так как РКТ-206 легко приобрести и это не слишком дорого. По результатам сами можете прикинуть, насколько это целесообразно. Статья получилась неожиданно объемная, но без досконального копания в мелочах тему рассмотреть не получается.
Читать дальше →

Ближайшие события

Разгон Мандельброта: SIMD с бубнами, OpenMP и CUDA

Уровень сложностиСредний
Время на прочтение16 мин
Количество просмотров3.7K

Построение множества Мандельброта — классический пример чрезвычайно параллельной задачи (embarrassingly parallel problem).

На первом курсе я впервые столкнулся с такой проблемой: тогда мы изучали SIMD-инструкции в курсе архитектур вычислительных систем. Эта тема сразу меня увлекла, и я захотел углубиться в дальнейшие оптимизации, но в течение семестра мне не хватало ни времени, ни знаний. Спустя год я решил восполнить этот пробел.

Вначале мы разберем наивную реализацию, поиграемся с интринсиками (intrinsics) и, не теряя переносимости, заставим компилятор генерировать нам SIMD-инструкции. Далее добавим многопоточность и в заключение обесценим все наши старания несколькими строчками на CUDA.

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

Читать далее

Векторизация в RISC-V. Основы

Уровень сложностиСложный
Время на прочтение13 мин
Количество просмотров5K

Многие современные вычислительные задачи, в частности повсеместная обработка изображений и звука или работа с матрицами для ИИ, хорошо поддаются параллелизации на уровне данных.  Чтобы ускорить такие вычисления, производители процессоров добавили в архитектуры специальные SIMD инструкции, которые позволяют работать за одну инструкцию сразу с несколькими элементами.

В процессорах архитектуры x86 SIMD инструкции добавляются по принципу ad hoc. Из-за такого подхода, легаси и требований обратной совместимости в x86 накопилось много проблем.

Архитектура RISC-V относительно молодая, и при её разработке учтён прошлый опыт. В основе подхода к SIMD в RISC-V заложили идею чистого векторного процессора.

В этой статье рассмотрим основные принципы работы векторного процессора и базовые векторные операции с памятью и арифметикой.

Читать далее

Путь от Кода до Бинарного Файла

Уровень сложностиСредний
Время на прочтение4 мин
Количество просмотров4.2K

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

Читать далее

Как код С выполняется на процессоре ARM: разбор ассемблера

Уровень сложностиСредний
Время на прочтение8 мин
Количество просмотров3.4K

При вызовах функций на языке С активно используется стек, который также именуется «стек вызовов». По мере того, как мы вызываем функции, они формируют так называемый «стек кадров». При каждом вызове функции образуется кадр, и эти кадры укладываются в стеке, где под них выделяется место. Далее в кадре из стека выделяется память под переменные и промежуточные значения. В кадре стека также содержится указатель на предыдущий кадр и значение счётчика команд. Та команда, которой оно соответствует, должна быть выполнена, как только кадр будет вытолкнут из стека. Далее давайте дизассемблируем вызовы функций в C, чтобы понять, как устроен стек кадров в ассемблере для ARM.

Читать далее

Сборка компьютера sap-1 (компьютер Бена Итера) в игре Turing Complete

Уровень сложностиПростой
Время на прочтение6 мин
Количество просмотров3.3K

Здравствуйте, меня зовут Дмитрий. Сегодня я хотел бы рассказать вам про очень интересную игру Turing Complete. Я назвал бы её симулятор разработчика компьютеров. А также мы прямо в этой игре соберем компьютер SAP-1 более известный как компьютер Бена Итера.

Сразу скажу что мне игра очень понравилась. Ну вот знаете иногда про игру все говорят какая крутая игра, а ты в неё поиграешь и думаешь. Ну игра ничего особенного. А иногда встречаются игры про которые никто не говорит особо, но стоит в неё начать играть, как обнаруживаешь что ты просто не можешь от неё оторваться. Как раз эта игра относится ко второму типу. У меня такое было c Factorio я в неё тоже долго не мог перестать играть. Так что возможно я буду чуть-чуть предвзятым.

Читать далее

Реверс-инжиниринг 128-битного дракона

Время на прочтение12 мин
Количество просмотров6.8K


КДПВ для этой статьи сгенерировала программа размером всего в 16 байт. Под катом разберёмся в том, как в столь скромном объёме сумел спрятаться дракон и какие силы поддерживают его жизнь. Для лучшего понимания происходящего мы портируем эту красоту на JavaScript.

Читать дальше →

Маленький bool Дума

Уровень сложностиПростой
Время на прочтение11 мин
Количество просмотров5.4K

Должен признать, у меня есть некая особая любовь к классическому DOOM. Несмотря на то, что игре уже 31 год, в нее все еще весело играть самому (хотя и выходит у меня так себе) или просто смотреть на то, как другие в нее играют (вот в этом я показываю себя лучше); и поскольку исходный код игры открыт, ей можно наслаждаться на любой современной платформе — ПК, смартфон, камера, осциллоскоп — да и вообще на любой вещи, которая придет вам в голову. В результате чего, благодаря ряду обстоятельств, я оказался меинтейнером нескольких связанных с DOOM пакетов в Fedora Linux.

Итак, за несколько месяцев до нового релиза, проект Fedora Linux осуществляет массовую сборку всех пакетов. Это имеет несколько преимуществ — позволяет убедиться в совместимости ABI, обновить статически линкуемые зависимости, использовать новые оптимизации компилятора и так далее. Как бы то ни было, с приближением релиза Fedora Linux 42 в середине апреля, пришло время для массовой пересборки, и как часто бывает, не все пакеты выжили. Одним из пакетов, которые не удалось собрать оказался chocolate-doom.

Читать далее
1
23 ...