Сайзкодинг: искусство создавать маленькие программы
easy

Сайзкодинг: искусство создавать маленькие программы

Чем меньше, тем лучше

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

Что такое сайзкодинг

Сайзкодинг — это искусство создавать программы размером от 256 байт и меньше для разных типов процессоров. Для сравнения: это всего на 37 байт больше, чем занимает этот абзац, если его сохранить в однобайтной кодировке.

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

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

Revision — крупнейший фестиваль, посвящённый демосцене
Revision — крупнейший фестиваль, посвящённый демосцене

Какие трюки используют при сайзкодинге

Основной инструмент сайзкодеров — язык ассемблера. Он позволяет писать код, который напрямую работает с железом. В ассемблере используются мнемоники — короткие символические имена, представляющие машинные команды (например, MOV, ADD, SUB). 

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

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

Допустим, есть ассемблерная инструкция mov ah, 37h, которая перемещает значение в регистр. В машинном коде она представлена как два байта: B4 37:

  • B4 — это команда mov ah, (перемещение значения в регистр ah).
  • 37 — это значение, которое перемещается в ah.

Если процессор интерпретирует байт 37 сам по себе, то распознаёт его как команду AAS (корректировка ASCII после вычитания). То есть один и тот же байт 37 можно использовать в разных контекстах: не нужно добавлять новую инструкцию, а можно взять уже имеющийся байт.

Платформы для сайзкодинга

Маленькие программы пишутся практически под любые платформы. Наиболее популярные: x86/DOS, ARM, RISC-V, виртуальные консоли типа TIC-80 или PICO-8, а также классические 8-битные и 16-битные системы Commodore 64, ZX Spectrum и Atari ST. 

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

Платформы для сайзкодинга

Разметка страницы состоит из элемента:

<pre id=p></pre>

А вот цикл для создания строки:

n = setInterval("for(n+=7,i=k,P='p.\\n';i-=1/k;P+=P[i%2?(i%2*j-j+n/k^j)&1:2])j=k/i;p.innerHTML=P", k = 64)

Для консоли TIC-80 пишут игры на JavaScript или Lua, и их можно портировать на другие платформы. Игра на 128 байт для TIC-80 может занимать всего 64 байта на x86. Мы уже рассказывали, как раньше писали игру для приставок: здесь всё почти так же. 

На сайте консоли есть онлайн-редактор для написания кода на Lua, там же есть встроенный редактор карт и спрайтов. Можно не только написать свою игру, но и поиграть в другие.

Консоль TIС-80 для создания маленьких игр и программ
Консоль TIС-80 для создания маленьких игр и программ

Платформа для «классического» сайзкодинга — это x86/DOS. Она предлагает прямой доступ к системным ресурсам и возможность написания программ, использующих системные вызовы DOS или BIOS. В результате получаются программы в формате .COM.

Есть программы на ассемблере x86, которые изначально были написаны на C, а затем уменьшены вручную. Есть программы на ассемблере ARM2, созданные для RISC OS, которые работают как на современном оборудовании, например Raspberry Pi, так и на оборудовании Acorn 1987 года.

Демосцена

С сайзкодингом тесно связана демосцена. Эта субкультура зародилась в 1980-х годах с появлением первых домашних компьютеров Commodore 64, ZX Spectrum и Amiga. Изначально демосцены были простыми программами, которые демонстрировали возможности графики и звуковых эффектов. Со временем демосцена превратилась в самостоятельное направление искусства и программирования, включающее создание сложных графических и звуковых композиций.

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

Вот пример такого интро для MS-DOS:

Демосцена

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

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

Примеры программ

Написать программу, которая будет генерировать вот такой лабиринт, можно задействовав всего 10 байтов или 6 строчек ассемблерного кода: 

Сайзкодинг: искусство создавать маленькие программы

Изначально программа занимала 42 байта, но сайзкодеры смогли уменьшить её до 10, используя множество оптимизаций:

init: 
  scasb 
  salc 
  and al,''-'/' 
  add al,'/' 
  int 29h 
  jmp init

Код представляет собой бесконечный цикл, который изменяет значение в регистре и выводит соответствующий символ на экран. Сначала выполняется несколько операций над значением, затем выводится символ, соответствующий этому значению. Затем цикл повторяется. В результате программа непрерывно выводит на экран символы, которые изменяются в зависимости от текущего состояния регистра.

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

А такая программа для Linux занимает 64 байта:

Сайзкодинг: искусство создавать маленькие программы

Здесь код на языке ассемблера x86 использует логическую операцию XOR для генерации графических паттернов. Используя целые числа и простые арифметические операции, программа создаёт графические эффекты. Основной цикл бесконечно повторяет операции, изменяя цвет и положение каждого пикселя в буфере, что создаёт динамический эффект. 

Зачем это вообще нужно?

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

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

Сайзкодинг отчасти сохраняет культуру прошлого, когда вычислительных мощностей и памяти было очень мало. А ещё создавать минималистичные программы — это просто интересное занятие :-)

Редактор:

Инна Долога

Обложка:

Алексей Сухов

Корректор:

Ирина Михеева

Вёрстка:

Маша Климентьева

Соцсети:

Юлия Зубарева

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Вам может быть интересно
easy