Обновить
64K+

Assembler *

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

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

Пишу алгоритм FFT на Си для процессора Эльбрус: прямая векторизация

Уровень сложностиСложный
Время на прочтение191 мин
Охват и читатели9.1K

Данная статья является продолжением предыдущей статьи.
Здесь рассматривается вариант прямой векторизации алгоритма FFT.
Перед чтением рекомендуется бегло ознакомиться с предыдущей статьёй.

Читать далее

Новости

Положил http:// в строку, и ассемблер молча собрал 0 байт

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели8.9K

Мой ассемблер резал исходник построчными правилами: срезал комментарий, искал двоеточие, делил по запятым. Я заменил это одним проходом с состоянием и попутно проверил, нельзя ли было обойтись заплатками.

Нельзя: вторая заплатка ломает то, что починила первая.

Куда делись байты?

Упаковщик наносит ответный удар: ZA как машина транспонирования

Уровень сложностиСложный
Время на прочтение9 мин
Охват и читатели6.1K

В этой части мы вернёмся к работе, которую предыдущие главы принимали как готовую: упаковке. Сначала найдём скалярную ловушку в упаковке B, затем используем ZA как машину транспонирования, после этого разберём 128-битный случай для комплексных чисел и правило корректности для общего PACKM_KER. В финале соберём весь цикл одной дугой: от FMOPA до работающей субконфигурации BLIS для Apple SME.

Читать далее

Комплексный GEMM: четыре вещественных внешних произведения в одном флаконе

Время на прочтение8 мин
Охват и читатели6.6K

В этой части мы сначала отделим прямой комплексный путь от готового метода 1m; затем покажем конфликт между чередующимся форматом памяти и раздельной арифметикой внешних произведений; после этого разберём четыре вещественных внешних произведения, расслоение через svuzp, эпилог с комплексными alpha и beta, а в конце — почему сопряжение остаётся работой упаковщика. Следующая часть вернёт нас к упаковке и к тому месту, где эта граница ответственности особенно важна.

Читать далее

Вставай, Василий: как мы отобрали у пульта право поднимать гуманоида

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели7.6K

Может ли робот встать по голосовой команде, если производитель это запретил?

Гуманоид Walker Tienkung поднимается на ноги только с физического пульта: короткое нажатие кнопки будит моторы и проводит самодиагностику, а длинное — ровно секунда удержания — поднимает из нулевой позы в стойку. Мы решили отдать весь этот путь голосу и быстро упёрлись в проблему: наши программные «нажатия» система молча игнорировала, а переход «встать» оказался заблокирован намеренно — команда принималась без ошибки, но робот не реагировал.

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

Читать далее

vm5277: Java-синтаксис и ООП для 8-бит МК без оверхеда

Уровень сложностиПростой
Время на прочтение21 мин
Охват и читатели9.4K

Java-синтаксис на 8-битных микроконтроллерах? Без виртуальной машины?

Исторически в эмбеддеде правит Си. Но Си — это вечные malloc/free, утечки памяти, выходы за границы массива и дебаг с осциллографом.

Я разрабатываю vm5277 — монолитный тулкит и язык J8B с Java-подобным синтаксисом. Он компилирует строгий ООП-код напрямую в нативный, оптимизированный ассемблер.

Что под капотом:

Управление памятью: через Reference Counting (new без free и без Garbage Collector).

Полиморфизм интерфейсов: спрятан во Flash (без оверхеда в ОЗУ).

Типы данных: встроенный 16-битный примитив fixed (Q7.8) вместо тяжелого float.

Оптимизация: тотальный Dead Code Elimination (в прошивку идет только то, что реально вызвано).

Проект в стадии суровой Альфы. Код открыт на GitHub, десятки примеров (от мигания диодом до драйверов периферии).

Читать далее

Написал свой ассемблер, чтобы понять, откуда берётся ff010113. Почти половину моей программы он выдумывает

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

Написал свой ассемблер, чтобы понять, откуда в дизассемблере берётся ff010113. Заодно посчитал, сколько строк моей программы процессор вообще не умеет исполнять, и проверил это на четырёх наборах команд, включая живой ESP32 на столе. На кристалле первая программа серии сломалась: она пишет в UART быстрее, чем провод успевает передавать, и в эмуляторе этого не видно.

Что сказала плата?

skitter-creek-bath-salts — обход аппаратной изоляции памяти в современных CPU

Уровень сложностиСложный
Время на прочтение30 мин
Охват и читатели15K

Или как получить полный доступ к изнанке CPU через скремблирование DRAM — PSP, C6, микрокоду, среде SMM и всему остальному, что не попало на страницы спецификации.

Всё-таки не всегда &x == &x...

Через вмешательство в работу контроллера DRAM можно сделать так, что обращение по определённому адресу будет вести в любую нужную область памяти. skitter-creek-bath-salts изменяет нижние слои структуры памяти, перестраивая трансляцию физический адресов DRAM. Такой скрэмблинг раскрывает защищённые области памяти, в том числе изолированные зоны, которые не видит даже само ядро. Когда ломается трансляция памяти, следом рушатся построенные на ней механизмы безопасности, и мы получаем доступ буквально ко всему.

Читать далее

История одного бага

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

В последние 5 лет, мы разрабатываем устройства с уровнем функциональной безпосности SIL3 (в части встроенного ПО). Это накаладывает кучу ограничений, например, абсолютно запрет на использование не сертифицированных по функциональной безопасности средст, типа Cube, или компилятров GNU и Clang, только сертифицированные средства типа IAR Workbench Function Safety.

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

Читать далее

Двойная точность: в основном «найти и заменить», плюс два настоящих сюрприза

Уровень сложностиСложный
Время на прочтение7 мин
Охват и читатели7.5K

В этой части мы используем sgemm как шаблон и проверим, что действительно меняется при переходе к dgemm: сначала пройдём скучную часть с удвоенными ширинами, затем разберём прямоугольный тайл 16×32, после этого — отдельный бит возможностей FEAT_SME_F64F64 и динамическую регистрацию ядра. Следующая часть будет устроена иначе: там меняется не только ширина элемента, но и сама форма данных.

Читать далее

Написание ядра ОС с нуля. Часть 3 — Пропуск в высшую лигу

Уровень сложностиСложный
Время на прочтение15 мин
Охват и читатели12K

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

В этой статье мы перейдем в полноценный, современный C++23, и все еще останемся на голом железе. Настроим страницы, GDT и перейдем в 64-битный режим.

Читать далее

Как устроен современный антивирус: поведенческий анализ, драйверы, архитектура

Уровень сложностиСложный
Время на прочтение28 мин
Охват и читатели11K

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

Собственно, рассмотрим примитивный пример в контексте поведенческого анализа. В системе появляется новый процесс с именем winloggon.exe - уже здесь внимательный наблюдатель заметит проблему, легитимный процесс называется winlogon.exe, а одна лишняя буква в имени для вируса вполне может оказаться попыткой замаскироваться под системный процесс под невнимательность пользователя. После инициализации наш герой совершает первую ошибку: обращается к реестру и прописывает себя в Run.

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

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

Ошибка третья. После чего в игру вступает антивирусный WFP драйвер - Windows Filtering Platform. Сетевой стек Windows позволяет системе защиты получать информацию о сетевых операциях и принимать решение, разрешать соединение или нет. В результате winloggon.exe, который только что прописал себя в автозагрузку, создал подозрительный файл и теперь пытается установить соединение наружу, оставляет ещё один вполне заметный след.

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

Читать далее

Микроядро SME2 sgemm: 1024 умножения-сложения за проход

Уровень сложностиСложный
Время на прочтение8 мин
Охват и читатели7K

В этой части мы возьмём первый из пропусков BLIS — микроядро sgemm; сначала зафиксируем форму аккумулятора 32×32 в четырёх тайлах ZA, затем разберём горячий цикл по K, потом эпилог с alpha, beta и ловушкой NaN, а в конце посмотрим, какие числа производительности даёт именно это ядро. Следующая часть оставит структуру почти той же, но заменит геометрию тайла и условия существования ядра.

Читать далее

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

Написание ядра ОС с нуля. Часть 1

Уровень сложностиСложный
Время на прочтение7 мин
Охват и читатели19K

Когда я только знакомился с OSDev, я очень долго искал соответствующие материалы. Находил и на YouTube, и на Habr, и просто какие‑то англоязычные сайты (тогда я не сильно знал английский). Но почти все что я находил было либо незаконченным, либо недостаточно понятным и полным.

В этой статье я постараюсь рассказать все так, как ожидал я это от других.

Читать далее

Нельзя просто взять и прочитать 64-битный SysTick на CH32V203

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

Когда я начал работать с CH32V203G6U6 и обнаружил, что там есть 64-битный аппаратный таймер, то подумал: ух, это же отлично, раз таймер аппаратный, то и о чтении/записи заботится сам микроконтроллер. И какое-то время это не вызывало вопросов. А потом…

Читать далее

Как я написал PID 1 для контейнеров на чистом ассемблере: x86-64 и ARM64

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

Не потому, что контейнерному миру срочно нужен ещё один init. Есть Tini, есть docker run --init, и для большинства production-сценариев я бы по-прежнему начал именно с них.

Мне скорее хотелось разобрать задачу до самого нижнего уровня: без libc, без runtime, напрямую через Linux syscalls. Заодно проверить, насколько сильно будет отличаться одна и та же реализация на x86-64 и ARM64.

В итоге из небольшого эксперимента получился mini-init-asm: PID 1, который запускает приложение в отдельной process group, передаёт сигналы всей группе, собирает zombie-процессы и умеет корректно завершать контейнер с exit code приложения.

Позже туда добавились subreaper mode и простой restart-on-crash. А сам проект в итоге доехал сначала до Debian unstable, а затем и до testing.

Но началось всё с вопроса: что вообще должен уметь нормальный PID 1 внутри контейнера?

Читать далее

Проектируем с нуля калькулятор на FPGA. Часть 10: Всё работает

Время на прочтение5 мин
Охват и читатели9.6K

← Девятая часть

В предыдущих постах мы подробно разбирали каждый слой: CPU, арифметику, скриптовый интерпретатор, оборудование. Вот, что окончательный отчёт о синтезе Quartus сообщает обо всех них: в готовой архитектуре используется 1593 логические ячейки из доступных в EP2C5 4608 (35% чипа) с 594 выделенными логическими регистрами и 17 блоками памяти M4K. Сам модуль CPU занимает 1173 из этих логических ячеек и 400 регистров. Остальная логика отдана периферии: драйверу ЖК‑дисплея (154 логические ячейки), сканеру клавиатуры (97), интерфейсу термопринтера (64), таймеру CTC (49) и аппаратному PRNG (20). 12 блоков памяти M4K занимает ROM микрокода (49152 бит: это полная программа калькулятора), 2 блока — ROM скриптинга (8192 бита), 1 — ROM BCD‑констант, 1 — таблица поиска для BCD‑умножения внутри CPU и 1 блок — ОЗУ. Меня это очень радует: полнофункциональный научный калькулятор уместился в 35% небольшой дешёвой FPGA.

Читать далее

wake up: демо в 16 байтах

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

В детстве я учился программированию на старом IBM PC с монохромным зелёным монитором, поэтому давно хотел создать программу для этой системы. За последние пятнадцать лет я написал более чем сотню небольших интро. В последнее время я был не так активен, но потрясающее интро «Rainbow Surf» автора Plex размером всего 16 байт мотивировало меня снова вернуться к старым наброскам и взяться за работу.

Создание этой программы сопровождалось привычными экспериментами. Я развлекался с клеточными автоматами в графике и звуке, а также исследовал трюки sizecoding. В частности: а) полиморфные ассемблерные команды (наподобие add [bx+si],al, имеющую машинный код 0x0000) б) переход в середины команд для экономии байт и многократного использования опкодов. Из сотен мелких экспериментов мне приглянулся один, интересный одним только своим названием.

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

В моём интро «M8trix» 2014 года по экрану уже бегали псевдослучайные буквы (в 8 байтах, а потом и в 7), но мне всегда было интересно, как добавить к ним красивый звук. Но хронологически в разработке «wakeup» я сначала занимался звуком. Хорошим подзаголовком к статье мог бы быть «16 байт, превращающие звук треугольника Серпинского в дождь символов из „Матрицы“».

Примечание: на каждом такте времени новая строка треугольника Серпинского а) воспроизводится через динамик б) отрисовывается на экране с шагом 56. Можно ощутить движение, но не увидеть его, потому что оно имеет «ширину» 8192 пикселей, но одна строка символов состоит всего из 80 байт. Если бы экран был гораздо больше, то можно было бы увидеть треугольник. Или если не пропускать пиксели и рисовать и все одновременно, он тоже был бы виден.

Читать далее

BLIS: недостающую среднюю ступеньку построили тридцать лет назад

Время на прочтение8 мин
Охват и читатели7.9K

В этой части мы начнём с тупика, в который приводит голый цикл FMOPA; затем покажем, какую часть GEMM BLIS уже построил за нас; после этого разберём пять циклов BLIS и место микроядра внутри них. Финал главы должен сделать дальнейший план конкретным: что именно нужно добавить для Apple SME, а что уже относится к готовой «мебели» фреймворка.

Читать далее

Как я перестал бояться и полюбил ассемблер

Уровень сложностиПростой
Время на прочтение14 мин
Охват и читатели24K

Эта статья посвящена путешествию в мир ретропрограммирования. Надеюсь, в ней у меня получится передать вам то чувство восхищения, которое я испытал и которое заставило меня написать этот пост. Пост о том, как создавать ПО для компьютерной системы Atari ST, выпущенной в 1985 году.

Atari ST относится ко второй крупной волне домашних компьютеров. Первая волна, созданная на основе 8-битных CPU, принесла в наши дома такие знаковые машины, как Commodore C64 и Sinclair Spectrum. Вторую волну разрабатывали на основе 16-битных CPU; она породила Apple Macintosh, Commodore Amiga и, разумеется, Atari ST.

Atari ST 1040 STF с цветным монитором Atari SC1224

Типичный Atari ST (например, 1040 STFM) имел CPU Motorola 68000 с тактовой частотой 8 МГц и 1 МБ ОЗУ; он загружал ПО с 3,5-дюймовых гибких дисков. Его графические возможности состояли из монохромного режима высокого разрешения 640x400 и 16-цветного режима 320x200, получившего наибольшую популярность в играх.

Рабочий стол GEM Atari ST имел интерфейс, очень похожий на разработанный Xerox и Apple, у него были диспетчер файлов, иконки и многооконность. Это его монохромная версия высокого разрешения.

Если у вас нет реального Atari ST, то его можно просто эмулировать на современном компьютере. Первые эмуляторы появились ещё в 90-х. Хорошим считается Hatari, который существует для большинства современных платформ. В эмуляторе также есть современные инструменты разработки. В прошлом приходилось пользоваться неуклюжим ПО разработки, которое загружалось с дискет, а сегодня можно просто писать всё в VSCode и компилировать современным GCC. У нас есть доступ к современным графическим редакторам наподобие GIMP, и мы даже можем просить помощи у ИИ.

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