Обновить
64K+

Assembler *

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

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

Проектируем с нуля калькулятор на FPGA. Часть 9: погоня за последним разрядом

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

← Восьмая часть

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

Но «большинство» это не «все», а «примерно 12» — это не 15-16 разрядов, которые может и должна обеспечивать 16-разрядная BCD-машина. Существовали пограничные случаи, в которых результаты оказывались совершенно неверными. Имелись итеративные алгоритмы с точностью приемлемой, но не такой, какой она могла быть. Кроме того, в процессе тестирования я обнаружил ошибки, при отладке которых обнаружились фундаментальные баги в коде прототипа на C++. Это привело меня в смятение, ведь для их устранения мне бы пришлось переделать заново код прототипа. В конечном итоге, так я и поступил. Старый код я оставил в репозитории (Pathfinding/Methods) и с нуля разработал совершенно новую версию (Pathfinding/Proof). Я пообещал себе, что занимаюсь этим последний раз в жизни, поэтому стремился делать всё идеально.

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

Читать далее

Новости

Что такое 10 REM"_(C2SLFF4, или как в комментарий 1980 года спрятали машинный код

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

В июле 1980 года Recreational Computing напечатал листинг The Wizard's Castle — рогалика на BASIC для микрокомпьютера Exidy Sorcerer. Первая строка выглядела так: 10 REM"_(C2SLFF4 .

REM — это комментарий: интерпретатор его пропускает, писать туда что-то имеет смысл только для человека. Вот только читать здесь нечего, сплошная абракадабра из символов.

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

Читать далее

Пингвин в гостях у Дельфина, или UNIX‑like система на Flipper Zero

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

Когда на экране терминала появилось приглашение #, Flipper Zero уже сложно было назвать просто устройством для работы с радиопротоколами, NFC и инфракрасными пультами. Передо мной находился маленький Unix-подобный компьютер: с ядром, процессами, командной оболочкой и файловой системой на microSD.

Читать далее

Странные машины: как хакеры собирают процессор из данных

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

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

И почему тогда Apple платит до двух миллионов долларов за одну найденную уязвимость и выстраивает многоуровневую аппаратную защиту — а айфоны всё равно взламывают по нажатию одной кнопки?

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

Перед нами — Data-Only атаки, где взлом превращается в программирование на «невидимом» процессоре. Процессоре, команды которого — лишь побочный эффект работы нашей собственной программы.

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

Читать далее

Проектируем с нуля калькулятор на FPGA. Часть 7: микрокод для самодельного CPU

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

← Шестая часть

В предыдущем посте мы спроектировали CPU. Я определился с набором команд, написал ассемблер, проверил каждый опкод и создал процессор, работающий в кремнии (или, точнее, в FPGA Altera Cyclone II EP2C5T144C8, что тоже довольно близко). Но у нас пока нет осмысленного ПО (микрокода калькулятора) для запуска на «железе».

В этой части проекта оправдали себя все эксперименты с прототипами на C++, описанные в частях 2 и 3.

Когда я начал писать addsub.asm (самую первую команду, которую я портировал), то не смотрел на пустую страницу, задаваясь вопросом, как работает BCD-сложение. У меня уже имелась эталонная реализация на C++ (addsub.cpp в проекте Proto), верифицированная на тысячах тестовых векторов. Алгоритм был известен, пограничные случаи найдены и охарактеризованы. Я проработал поведение защитного разряда и бита фиксации. Оставалось лишь транслировать это всё на язык ассемблера; задача всё равно сложная, но совершенно иного уровня сложности, нежели изобретение алгоритма в процессе его написания.

Я хотел бы сделать упор на этот двухэтапный процесс, потому что может показаться, что без него можно обойтись. Написание кода прототипа на C++ с последующей ручной трансляцией на язык ассемблера кажется избыточной и долгой работой. Однако она перестанет казаться избыточной к моменту, когда вы будете отлаживать неочевидный пограничный случай округления в 16-ниббловом BCD-вычитании. Наличие золотого эталона, с которым можно выполнять сравнения, не избыточно: это единственное, что стоит между вами и неделями кропотливого труда или даже провалом проекта.

Читать далее

Технология ELAM: как детектируются уязвимые драйверы Windows

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

На дворе 2026 год, технологии развиваются, а хакеры становятся сильнее и изобретают новые способы обхода средств безопасности. Один из таких методов, который уже стал классикой в 2026 году — это BYOVD‑техника (Bring Your Own Vulnerable Driver). Суть проста: атакующий подсовывает в систему легитимный, но уязвимый драйвер, чтобы использовать его как рычаг для отключения защиты(например, чтобы убить процесс антивируса). То есть, в процессе атаки через BYOVD у хакера всегда есть уязвимый легитимный драйвер, но его ищут двумя путями.

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

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

Используется эта техника потому, что современные антивирусы стали слишком сильными. Если посмотреть под капот любому актуальному хорошему защитнику, мы увидим там как минимум 4 собственных драйвера, которые контролируют процессы, следят за подключением разных физических устройств (USB), следят за тем, чтобы вредоносный процесс не смог проэксплуатировать какую‑то уязвимость(например, подмена токена у системного процесса на свой).

Исходя из всего, что я описал выше, возникает логичный вопрос: как мы можем пресекать способы эксплуатации системы через BYOVD‑драйверы? Ответ на этот вопрос прост — нам нужна технология ELAM.

Читать далее

Stream compaction на NEON. Векторизуем copy_if

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

Как разогнать copy_if на NEON в 30+ раз без единой ветки в горячем цикле — эмулируем compress инструкцию, которой в NEON нет, через table lookup и немного битовой магии.

Читать далее

Методичка которую я формировал для себя, когда учил ассемблер x86-32. Ч.1

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

Небольшая статейка о самых-самых основах ассемблера х86 процессоров. Я расскажу вам о том, как всё работает и для чего вам нужно это знать, даже если вы обычный говнокодер)

Читать далее

Автомобильные сигнализации РФ и их безопасность. Часть 1

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

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

Забегая вперёд, скажу, что отчёты обо всех найденных недостатках были направлены производителям, а также во ФСТЭК России. Из ответа регулятора я узнал, что в качестве уязвимостей отчёты зарегистрированы не будут, так как «данное программно-аппаратное средство не используется на объектах ГИС и КИИ». Производители же сообщили, что описанные недостатки устранят в новых моделях сигнализаций. За информацией о том, что делать с уже существующими моделями, я рекомендую обращаться к производителям.

Читать далее

Проектируем с нуля калькулятор на FPGA. Часть 6: CPU

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

← Четвёртая и пятая части

Это самый длинный пост всей серии, потому что он посвящён главной части этого проекта — всё вращается вокруг CPU.

Почему бы просто не взять готовый CPU?

Кто-то может заявить: зачем заморачиваться проектированием собственного CPU? Есть куча маленьких хорошо задокументированных процессоров и дешёвых микроконтроллеров, способных исполнять прошивку калькулятора. Zilog Z80 не так сложно реализовать на FPGA, и я в этом уже убедился (проект A-Z80, находящийся у меня на GitHub). Подойдёт и 6502. Маленький встраиваемый RISC тоже прекрасно справится с этой работой.

Отвечу честно: это было бы не так интересно, потому что подобное уже много раз делали. Но есть и другие (более удобные для меня) причины.

Наш калькулятор построен на BCD (двоично-десятичном коде),в котором каждый десятичный разряд хранится в отдельном 4-битном полубайте (ниббле). Это правильный выбор для калькулятора, и он определяет всё дальнейшее. Z80 (и другие стандартные CPU) работает на уровне байтов. Для индексации регистра мантиссы из 16 нибблов с ориентированным на байты процессором пришлось бы постоянно жонглировать сдвигами, масками и двумя нибблами на байт. На каждом шаге режимы адресации вступают в конфликт со схемой данных.

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

Читать далее

Самодельный BIOS для микшерного пульта и запуск DOS на нём

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

В 1994 году у меня появился первый компьютер: Intel i486 DX2-66 с 4 МБ ОЗУ и жёстким диском на 512 МБ. На нём были установлены IBM OS/2 и Microsoft Windows 3.11. Следующие четыре года я апгрейдил эту машину каждые несколько месяцев, добавляя больше ОЗУ (до 16 МБ), привод CD-ROM и карту SoundBlaster. Так я научился апгрейдить эту машину, устанавливать новое ПО, а потом и писать ПО на BASIC. Но я ни разу не касался процесса запуска и тонкостей MS-DOS.

В 2026 году, 32 года спустя, я узнал из скриншотов DDX3216, что в Behringer использовался настоящий процессор 386. В моём мозгу сразу же активировались какие-то нейроны и я начал размышлять о том, можно ли запускать на этом устройстве ПО или даже полнофункциональную операционную систему. Для этого мне нужно было разобраться, как запускается система x86, когда управление перехватывает DOS и что необходимо для попадания в оболочку.

Читать далее

Remoded: разбираем демо-эффекты (часть 2)

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

И снова приветствую всех любителей олдскула, демосцены и олдскульной демосцены. Это вторая часть разбора DOS-демки "Remoded" и соответственно эффектов, основанных на аппаратных особенностях видеоадаптера VGA. Сегодня мы продолжим разбираться с аппаратным скроллингом, узнаем, что такое "xorfill" и как его правильно готовить, как эмулировать 12 тысяч цветов в 256-цветном режиме, а также познакомимся с другими технологиями прошлого столетия.

MOV AX, 13h; INT 10h

Динамический полиморфизм против std::variant с указателями: Разрушаем мифы о скорости std::visit (v.2*)

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

В экосистеме современного C++ прочно укоренилось мнение: классический динамический полиморфизм через виртуальные функции (vtable) и наследование — это устаревший, медленный и недружелюбный к кэшу процессора механизм. В качестве «серебряной пули» модно предлагать связку std::variant и std::visit. Если вы спросите любого виртуального умника (ИИ) он до последнего будет убеждать вас что std::variant и std::visit всегда(!) лучше чем виртуальные функции, даже не сомневайтесь. Проблема в том что с таким отношением вы во многих случаях просто лишаете себя выбора адекватного технического решения. Решения адекватного условиям конкретной задачи с необходимостью диспетчеризации вызовов. По интернету кочуют статьи, утверждающие, что std::visit выполняет диспетчеризацию за фиксированное время O(1) и полностью уничтожает старый добрый ООП-подход, но вы должны понимать что не существует универсальных решений на все случаи жизни.

А что если мы попробуем уравнять начальные условия использования обеих техник диспетчеризации и будем использовать вариант с указателями, а не с эмплейс-объектами: std::vector<std::unique_ptr <BaseClass>> и std::vector<std::variantstd::unique_ptr<TypeA>, std::unique_ptr<TypeB>,std::unique_ptr<TypeC>>> в условиях раздельной компиляции классов и кода который делает вызовы (зачем это надо?).

Читать далее

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

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

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

Примерно полгода назад я познакомился с VLIW‑процессором Эльбрус-8СВ. На тот момент у меня уже был опыт написания кода на ассемблере для VLIW‑процессора TMS320C66. Поэтому я захотел сделать нечто похожее для Эльбруса, а именно, написать алгоритм FFT на ассемблере. Но из‑за нехватки документации на инструкции процессора мне пришлось начать с реализации какого‑нибудь простого алгоритма на Си, чтобы изучать его ассемблерный вывод.
По результатам этой работы была опубликована предыдущая статья на Хабре.

После завершения той статьи я решил попробовать написать алгоритм FFT на Си для Эльбруса. Работа ещё не завершена, но определённые успехи уже есть (сравнение с EML присутствует). В этой статье я хочу поделиться полученными на данный момент результатами.

Читать далее

Охота за багом: почему для прохождения Pizza Tycoon достаточно одного Парижа

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

В новом релизе Pizza Legacy v0.1.0 появилась возможность выиграть игру, как в оригинале.

Когда я играл в Pizza Tycoon (1994 год) в детстве, то не особо задавался вопросом, как победить. Мне просто нравилось открывать рестораны и придумывать пиццы, а также приторговывать оружием для финансирования роста моей империи пиццы. Но выигрыш? Я никогда до него не доходил и, вероятно, даже не задумывался о нём.

Когда я принялся за проект воссоздания этой игры, то начал изучать файлы данных Pizza Tycoon, обнаружив графический файл ENDE.VGA и текстовый файл ENDE.E, сообщающий нам, что происходит в случае выигрыша:

Первая строка ENDE.E:

Вы достигли немыслимого! Вы — король всего западного рынка фастфуда! Вы — тот самый, МАГНАТ ПИЦЦЫ.

Это даёт нам понять, что игру как-то можно выиграть, но не как именно.

Я просто забыл об этом вопросе, ведь мне предстояло реализовать столь многое до того, прежде чем задумываться о победе игрока, но однажды наткнулся на пост «Я "выиграл" в Pizza Tycoon? (Как это произошло?)». После нахождения этого поста мне стало любопытно, но не настолько любопытно, чтобы заниматься расследованием, поэтому я поискал условия конца игры в ассемблерном коде и попросил Claude проанализировать их. Он сказал следующее:

end_of_week_processing раз в неделю проверяет, есть ли у текущего игрока >= доля рынка 5% во ВСЕХ 10 городах.

Это соответствует моим представлениям: логично с точки зрения геймплея и текста, найденного в ENDE.E. Однако это не соответствовало написанному пользователем Reddit: он утверждал, что у него были рестораны только в Париже и Берлине; возможно, он опустил какие-то подробности или у него просто был повреждённый файл сохранения? Я написал ему, но не получил ответа...

Читать далее

Relocation-Based Predicate — врём в IDA по-новому

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

Базовые механизмы Windows создавались для защиты программ, но сегодня мы заставим их работать против реверс-инженеров. Показываю новую технику обфускации: как с помощью ASLR и таблицы релокаций создать ложную ветку выполнения, которая сейчас остаётся абсолютно невидимой для статических анализаторов.

Читать далее

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

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

Сегодня видел план вводного курса, написанный начинающей американской преподавательницей. План иллюстрирует распостраненную ошибку — неправильный порядок подачи материала:

Читать далее

Что именно делал компилятор: как ассемблер помогает разобраться в производительности кода на C++

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

Расскажу вам одну историю о том, как смог прокачаться в качестве C++-программиста. Мне в этом помогло не чтение стандарта. Я тогда ещё не понимал до конца метапрограммирование с использованием шаблонов (честно говоря, прямо сейчас эту тему изучаю). Нет, просветление наступило, когда я всмотрелся в целую простыню кода на ассемблере x86–64, но не запаниковал, а подумал: “O, нет, нет. ЧТО ТАМ сделал компилятор?”

Читать вывод компилятора — это не какое-то мистическое тёмное искусство, которое практикуют только подстриженные в барбершопах разработчики компиляторов, с закрытыми глазами разбирающиеся в выделении регистров. Это навык. Его можно усвоить, затем в нём напрактиковаться, и результат вас очень удовлетворит. Овладев этим умением, вы больше никогда не будете писать «умные» абстракции как раньше. 

Читать далее

VBoxGuest для KolibriOS: архитектура и устройство драйвера

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

VBoxGuest — драйвер гостевых дополнений для KolibriOS, написанный с нуля на FASM.

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

Сравнение с upstream-реализациями для Linux/Windows/FreeBSD. Для системных программистов и энтузиастов OSDev.

Читать далее

CactOS

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

Эта статья — не руководство по написанию ОС и не туториал. Это срез архитектуры работающего ядра, которое прошло путь от вечных Page Faults и Segmentation Faults (в ring 3) до системы с 95 системными вызовами, сетевым стеком, COW и MLFQ-планировщиком. Все исходники открыты под GPLv3.

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