<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <language>ru</language>
    <title>Язык ассемблера</title>
    <description>Рубрика, посвященная самому приближенному к железу семейству языков, а также тому, как на низком уровне работают трансляторы кода.</description>
    <link>https://tproger.ru/tag/asm</link>
    <atom:link href="https://tproger.ru/tag/asm/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Sun, 04 Oct 2026 19:44:30 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>Язык ассемблера</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Как я писал ОС, но не под x86, а под RISC-V</title>
      <link>https://tproger.ru/articles/kak-ya-pisal-os-no-ne-pod-x86-a-pod-risc-v</link>
      <comments>https://tproger.ru/articles/kak-ya-pisal-os-no-ne-pod-x86-a-pod-risc-v?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[lmemq]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-ya-pisal-os-no-ne-pod-x86-a-pod-risc-v</guid>
      <description><![CDATA[<p>Решил разобраться, как устроены операционные системы изнутри, и написал свою простую ОС под RISC-V. Делюсь написанием многопоточности, сохранением регистров процессора и другими интересными кейсами</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-ya-pisal-os-no-ne-pod-x86-a-pod-risc-v">Как я писал ОС, но не под x86, а под RISC-V</a>»</p>]]></description>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Низкоуровневое программирование]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Операционные системы]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 23 Jul 2026 13:21:29 GMT</pubDate>
      <content:encoded><![CDATA[<h3>Введение и дисклеймер</h3><p>Сразу скажу - я не считаю себя втором Терри Дэвисом и тем более не хочу делать аналог Виндовс. Изначально я все это затеял только ради прикола и изучения ассемблера.</p><p>А, и если что - мне 14, но я не против любой критики. И да, я тоже как и большинство местами использовал ИИ. Я не сидел читал мануалы часами, просто гуглил или просил нейронку пояснить.</p><h3>Так а в чем же проблема x86_64?</h3><p>Я так скажу - я пробовал писать под эту архитектуру. Мне не понравилось, всякие режимы (которые за меня правда переключал загрузчик), да и местный ассемблер мне было лень изучать. Просто захотел писать под более новую архитектуру.</p><p>Не буду говорить, что RISC-V лучшая, но я просто выбрал ее. Прикол в том, что инструкции короткие, да и в целом достаточно перспективно. Хотя и тут были проблемы.</p><h3>Был драйвер, стала ОС</h3><p>Я ничего с нуля не писал.Все началось с пыток ИИ, когда я пытался выдавить из него то обращение по конкретному адресу для доступа к графике, то опрос портов, то еще что-то такое. Мне стало лень и я пошел искать что-то плюс-минус готовое. И я нашел его - <a href="https://github.com/CityAceE/qemu-ramfb-riscv64-driver">ramfb</a>. По сути я получил готовый указатель на фреймбуфер для вывода на экран… И все. Но и на этом большое спасибо авторам драйвера. Дальше началась моя ОС.</p><h3>А где хранить данные?</h3><p>А тут первая проблема - как таковой кучи у меня еще нету. Есть стек, который за меня выделил автор драйвера. Есть всякие глобальные переменные. Но что если мне нужно много памяти (например, под картинки) и я не знаю точный размер? И в добавок, кто вообще рисует напрямую на экран? Тут нужен некий массив пикселей, который будет лежать в памяти, а по нашей команде быстро перенесется на экран (называется backbuffer).</p><p>Под кучу взял 64 мб из памяти, так как Qemu, где запускается моя ОС, выделяет ей аж 128 мб, часть уже занята ядром и стеком, но бОльшая часть пустует. Сделал простенький список свободных и занятых блоков памяти.</p><p>Это когда ты делишь память на куски, каждый помечаешь как занятый или свободный. Нужно мало памяти - откусываем от большого куска блок. Блок освободился, а рядом есть другой свободный блок - соединяем в один большой.Сразу же добавил функцию, чтобы узнать сколько памяти занято. Сейчас, например, занято около 3-4 мб. Ну это учитывая, что backbuffer и занял почти 3.5 мб.</p><p>В оперативной памяти что-то типа</p><h3>Такая разная многопоточность</h3><p>Как я думаю большинство знает, если у процессора одно ядро, одновременно на нем может выполняться только одна задача-поток. Но мы же может останавливать задачу, запускать другую, останавливать, запускать еще другую и так много раз в секунду. Тогда будет казаться, будто бы у нас несколько задач выполняются одновременно.</p><h4>Многопоточность кооперативная</h4><p>Так мы можем сказать потокам, чтобы если один из них решит, что стоит сделать паузу, сам вызвал yield() и отдал процессор другому потоку. И я это сделал. Все что нужно было - сохранить s-регистры процессора (те, в которых лежат всякие важные значения), указатель на личный стек потока (размер стека задается при создании) и указатель на “дорогу назад” ra. То есть yield() сохраняет эту информацию потока А, затем вместо нее загружает информацию потока Б. И так по кругу.</p><p>Кстати, стеки самих потоков я выделял в той самой куче. Просто брал блок на пару кб и говорил потоку: “Это твой стек”.</p><p>Но у такого концепта есть проблема - зависает один поток, остальные перестают выполняться. Да и в целом писать yield() каждый раз сложно.</p><h3>Многопоточность вытесняющая</h3><p>Поэтому я и решил переписать все на вытеснение. Для начала я сделал так - каждые 100к тиков процессора сохраняются все регистры и пинается функция обработки прерываний. Таймер, по которому будет работать многопоточность - это тоже прерывание. Так же эта функция ловит ошибки по типу kernel panic. Это было сложнее - так как потоки не добровольно отдают процессор, приходится сохранять вообще все 32 регистра. Но криво-косо я написал это и функцию sleep(), во время которой функция простаивает, ее никто не трогает.</p><p>А тут еще и ИИ начал выдавать бред, пока я тестировал у меня… начинал выполняться основной код, все было хорошо, а потоки - нет. Я сам не вижу ошибку, ИИ тоже. Он то предложит заменить какую-то часть функции, то еще что-то такое. Наконец я вспомнил про замечательную штуку - gdb. Запустил, посмотрел… Оказалось так - цикл отрисовки экрана был слишком долгим, во время него вызывалось переключение потоков, а их еще не было кроме главного. В итоге я подумал что смысла создавать потоки в конце, после отрисовки, нет, и перенес их в самое начало. Удивительно, но все заработало.</p><h3>Немного про режимы</h3><p>Как выяснилось, в RISC-V есть 3 режима (точнее 4, включая гипервизор, но тут он мне точно не нужен) - M-mode с полными привелегиями, S-mode для ядра ОС (я думал что и мое его использует), ну и U-mode для пользователей, но до этого мои ручки еще не дошли.</p><p>Ну и по пути я случайно осознал, что мое ядро выполняется аж в М-режиме:</p><p>Вызываю я ecall из потока. Смотрю - kernel panic. В логах какой-то код “11”. Оказалось, это и есть ecall - в M-mode он 11, а в S-mode (в котором, как я думал, работало ядро, и который я пытался выловить) это 9. Ну когда я нашел, уже быстро исправил.</p><h3>Визуальчик</h3><p>Но в это время на сам экран эмулятора Qemu… Ничего и не выводилось. Совсем. Просто белый экран. Хотелось красоты.</p><p>Тогда я вспомнил, что день назад прикрутил qoi.h к моему коду. QOI - формат изображений. Выбрал я его, так как декодер легкий и его удобно использовать в любой ОС, где есть базовые функции.</p><p>Я аккуратно, разумеется, согласно лицензии, взял из pop os, которой когда-то пользовался, картинку для фона. Конвертировал ее в .qoi, а так как моя ос еще не умела читать с диска, перевел картинку в заголовочный файл .h. Весит правда много, но влезает.</p><p>Дальше я нашел шрифт (Liberation Mono от Red Hat), перегнал и его в .h. Честно, визуал меня не сильно интересовал, поэтому быстро попросил ИИ переделать функции вывода в консоль в функции вывода на экран. Проверил, просмотрел что и как сделано, получилось нормально для старта. Правда пока что в графической консоли нет нормальной перемотки и много чего другого.</p><h3>Вывод</h3><p>Конечно, еще нету даже ввода с клавиатуры, мыши, файловой системы (даже простой). Но я считаю, что вышло неплохо, пусть и далеко от уровня реальной ОС типа Линукса. Понятно, что код не очень-то красивый, достаточно простой. Статью я выкладываю больше просто чтобы разобраться самому в том, что я написал.</p><p>Если я не забью на код, хотел бы написать еще и MMU и переход в U-mode.</p><p>Для тех кому очень интересно - можете глянуть исходный код <a href="https://github.com/lmemq/mqos-rv">mqos</a>, там же будут инструкции по запуску.</p>]]></content:encoded>
    </item>
    <item>
      <title>KolibriOS 0.7.7: ОС на ассемблере, которая влезает на дискету</title>
      <link>https://tproger.ru/articles/kolibrios-0-7-7-os-na-assemblere-kotoraya-vlezaet-na-disketu</link>
      <comments>https://tproger.ru/articles/kolibrios-0-7-7-os-na-assemblere-kotoraya-vlezaet-na-disketu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kolibrios-0-7-7-os-na-assemblere-kotoraya-vlezaet-na-disketu</guid>
      <description><![CDATA[<p>KolibriOS 0.7.7 — российская ОС на ассемблере, которая помещается на дискету и работает на i586 с 8 МБ ОЗУ. Разбираем возможности и ограничения.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kolibrios-0-7-7-os-na-assemblere-kotoraya-vlezaet-na-disketu">KolibriOS 0.7.7: ОС на ассемблере, которая влезает на дискету</a>»</p>]]></description>
      <category><![CDATA[Низкоуровневое программирование]]></category>
      <category><![CDATA[Ретро]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Операционные системы]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Hardware]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Браузеры]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 04 Jul 2026 12:28:13 GMT</pubDate>
      <content:encoded><![CDATA[<p>В 2026 году операционная система, которая полностью умещается на 3,5-дюймовой дискете и загружается быстрее, чем вы успеваете отпить кофе, звучит как технологическая шутка. Но <b>KolibriOS 0.7.7</b> существует, развивается и даже имеет рабочий графический стол. Это не эмулятор и не демо: полноценная 32-битная ОС, ядро которой написано на ассемблере.</p><p>В своей колонке <i>Daily Drivers</i> редактор Hackaday Дженни Лист скачала ISO-образ, запустила KolibriOS на современном ThinkPad и удивилась: система выглядит зрелой, стабильной и по-настоящему быстрой. Разбираем, что это за проект, откуда он взялся и кому пригодится сегодня.</p><h2>Что такое KolibriOS</h2><p><b>KolibriOS</b> — российский форк MenuetOS, созданный в 2004 году. В то время как автор оригинального MenuetOS Вилле Турьянмаа переключился на закрытую 64-битную версию, сообщество вокруг русскоязычного порта сохранило код открытым и продолжило развивать 32-битную ветку. Название «Колибри» выбрано неслучайно: система маленькая и быстрая, как птица-колибри.</p><p>Проект поддерживается преимущественно разработчиками из России, Казахстана, Украины и Германии. Код распространяется под открытой лицензией, а сборки регулярно публикуются на официальном сайте и зеркалах сообщества.</p><h2>Версия 0.7.7</h2><p>Версия 0.7.7 продолжает философию предельного минимализма. Минимальные системные требования смехотворны по нынешним меркам: <b>1 МБ</b> места на диске, <b>8 МБ</b> оперативной памяти и процессор класса <b>i586</b>. При этом система выдаёт графический интерфейс, многозадачность и набор встроенных программ.</p><p>Дженни Лист отмечает, что на ThinkPad 2020-х годов KolibriOS загружается «в мгновение ока» и сразу показывает рабочий стол. Интерфейс выглядит пиксельным, как в 1990-х: нет сглаживания, есть ощущение ретро. Но при этом всё работает — без синих экранов и зависаний.</p><ul><li>KolibriOS 0.7.7 — 32-битная ОС с ядром на ассемблере, базовый образ весит около 1 МБ.</li><li>Минимальные требования: i586, 8 МБ ОЗУ, 1 МБ на диске.</li><li>В комплекте браузеры, игры, эмуляторы, графические редакторы и среда разработки.</li><li>Главное ограничение для повседневного использования — отсутствие поддержки HTTPS.</li><li>Лучше всего подходит для старого железа, тонких клиентов, обучения и ретрокомпьютинга.</li></ul><h2>Как устроена система</h2><h3>Ядро на ассемблере</h3><p>Большая часть KolibriOS написана на <b>FASM</b> — плоском ассемблере. Это объясняет крошечный размер исполняемых файлов и молниеносную загрузку: система не тратит время на инициализацию абстракций, слоёв совместимости и десятков фоновых служб.</p><p>Важная оговорка: несмотря на миф «всё на ассемблере», часть приложений и драйверов портирована или написана на C, Free Pascal, Oberon и даже Python. Но ядро, графическая подсистема и системные вызовы остаются ассемблерными.</p><h3>Файловые системы и загрузка</h3><p>KolibriOS умеет загружаться с CD/DVD, USB, жёстких дисков и даже с классической дискеты 1,44 МБ. Поддерживаются файловые системы FAT12/16/32, exFAT, NTFS и ext2/3/4. Есть варианты для Coreboot и загрузка прямо из Windows.</p><h2>Что внутри: программы и игры</h2><p>Несмотря на размер, KolibriOS поставляется с обширным набором софта. По данным сообщества, в образ входят более <b>250 программ</b>, включая текстовый процессор, просмотрщик изображений, графический редактор, музыкальный плеер, IRC-клиент и веб-браузеры.</p><p>Из игр и развлечений — порты эмуляторов, DOSBox, а также shareware-версии классики вроде DOOM и Wolfenstein 3D на полноценном CD-образе. Есть поддержка SDL, что позволяет переносить проекты с «больших» систем.</p><blockquote>Something this polished deserves a while to play around.</blockquote><h2>Главное ограничение: интернет без HTTPS</h2><p>Дженни Лист называет именно этот момент решающим: встроенные браузеры KolibriOS, включая Netsurf и Webview, не поддерживают HTTPS. Без этого современный веб практически закрыт: большинство сайтов, включая сам Hackaday, просто не откроются.</p><p>Это меняет статус системы с «основной ОС на каждый день» на «платформу для специальных задач». Почта, мессенджеры, облачные сервисы и онлайн-документация остаются недоступны без промежуточного прокси или другой машины.</p><p><b>Почему HTTPS сложно:</b><br />Современный TLS требует большой криптографической библиотеки, регулярных обновлений корневых сертификатов и поддержки множества алгоритмов. В условиях ОС размером в мегабайт это серьёзный архитектурный вызов, который сообщество пока не взяло в штатный комплект.</p><h2>Кому и где пригодится KolibriOS</h2><p>С учётом ограничений у KolibriOS остаётся несколько чётких сценариев применения. В России и соседних странах это особенно актуально: парки старого офисного и школьного оборудования часто содержат машины, которые официально «не тянут» современные ОС.</p><ul><li>Воскрешение старого железа. Pentium- и ранние Core-машины получают рабочий стол, браузер для локальных страниц и офисные утилиты.</li><li>Тонкие клиенты. Низкие требования к RAM и CPU делают KolibriOS кандидатом для терминалов с удалённым рабочим столом.</li><li>Обучение. Ядро на ассемблере, простые системные вызовы и небольшой кодовой базы — отличная площадка для изучения устройства ОС.</li><li>Ретрокомпьютинг. Запуск DOS-игр через эмулятор, классические 2D-игры и ностальгический интерфейс 1990-х.</li><li>Встроенные системы. Сборка Kolibri-A ориентирована на специализированное железо и железные проекты.</li></ul><h2>Как попробовать KolibriOS</h2><p>Попробовать систему проще всего в виртуальной машине. Скачайте ISO-образ с официального сайта, создайте VM с 64 МБ ОЗУ и загрузитесь с образа. Для реального железа подойдёт запись образа на USB-флешку или CD.</p><ul><li>Скачайте ISO или образ дискеты с официального сайта KolibriOS.</li><li>Для VM: создайте 32-битную машину с 64 МБ RAM и VESA-видео.</li><li>Для железа: запишите ISO на CD или USB через обычную утилиту.</li><li>Загрузитесь и выберите разрешение экрана из меню загрузчика.</li><li>Исследуйте меню «Пуск»: игры, утилиты, терминал и браузер.</li></ul><p>Если планируете использовать сетевые функции, проверьте совместимость сетевой карты по <a href="https://wiki.kolibrios.org/" rel="noopener noreferrer">списку оборудования</a>. Поддерживаются многие чипы Realtek, Intel и 3Com.</p><h2>Выводы</h2><p>KolibriOS 0.7.7 — это не замена Windows или Linux, а демонстрация того, какой отклик может давать компьютер, когда софт пишут под железо, а не под абстракции. В эпоху, когда операционки растут гигабайтами, проект напоминает: минимализм ещё жив.</p><p>Для российского читателя у KolibriOS есть дополнительный смысл: это открытый проект с русскоязычным сообществом, который можно изучать, дополнять и применять для решения практических задач — от перевода старого классного компьютера в рабочее состояние до обучения низкоуровневому программированию.</p><p>Главный вопрос — нужна ли вам такая система прямо сейчас. Если у вас есть старый 32-битный ноутбук, интерес к ассемблеру или просто ностальгия по быстрым ОС — попробуйте. А для повседневной работы с интернетом пока придётся держать под рукой что-то посовременнее.</p><p><b>Источники:</b></p><ul><li><a href="https://hackaday.com/2026/07/02/jennys-daily-drivers-kolibrios-0-7-7/" rel="noopener noreferrer">Jenny’s Daily Drivers: KolibriOS 0.7.7 — Hackaday</a></li><li><a href="https://distrowatch.com/kolibri" rel="noopener noreferrer">KolibriOS на DistroWatch</a></li><li><a href="https://wiki.kolibrios.org/" rel="noopener noreferrer">Официальная вики KolibriOS</a></li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Разработчик написал «Змейку» на ассемблере размером всего 54 байта — она помещается в QR-код</title>
      <link>https://tproger.ru/news/razrabotchik-napisal--zmejku--na-assemblere-razmerom-vsego-54-bajta---ona-pomeshhaetsya-v-qr-kod</link>
      <comments>https://tproger.ru/news/razrabotchik-napisal--zmejku--na-assemblere-razmerom-vsego-54-bajta---ona-pomeshhaetsya-v-qr-kod?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/razrabotchik-napisal--zmejku--na-assemblere-razmerom-vsego-54-bajta---ona-pomeshhaetsya-v-qr-kod</guid>
      <description><![CDATA[<p>Разработчик создал «Змейку» на ассемблере весом 54 байта — игра полностью помещается в один QR-код и запускается даже без ОС</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/razrabotchik-napisal--zmejku--na-assemblere-razmerom-vsego-54-bajta---ona-pomeshhaetsya-v-qr-kod">Разработчик написал «Змейку» на ассемблере размером всего 54 байта — она помещается в QR-код</a>»</p>]]></description>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Разработка игр]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Процессор]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 23 Oct 2025 06:40:40 GMT</pubDate>
      <content:encoded><![CDATA[<p>Разработчик под ником <b>donno2048</b> поместил легендарную <b>«Змейку»</b> в <b>54 байта</b> машинного кода — настолько мало, что весь исполняемый код помещается в один QR-код.</p><p>Проект <a href="https://github.com/donno2048/snake">опубликован</a> на GitHub и сопровождается демонстрацией, инструкциями и, непосредственно, самим QR-изображением.</p><h2>Как это работает</h2><p>Это x86-код, изначально рассчитанный на DOS. Есть и вариант, который не требует BIOS, загрузчика или операционной системы.</p><p>Автор использует тонкие приемы оптимизации — минимальные инструкции, хитрые трюки с регистрами и адресацией. И все это нужно чтобы уместить игровую логику и отрисовку в крошечный набор байтов.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-10-23/89cbac88-e7fb-48a5-b5ef-323708eed671.jpeg" alt="" /></figure><h2>Зачем все это</h2><p>Разумеется, это никакая не попытка заменить полноценную игру, а упражнение в минимализме: показать, как далеко можно зайти с низкоуровневыми оптимизациями.</p><p>В README автор прямо сравнивает размер в байтах с обычными программами.</p><h2>Практическое значение и эстетика</h2><p>Проекты вроде этого интересны двумя вещами:</p><ol><li><b>Техническая демонстрация</b> — они учат «компактному» мышлению и глубокому пониманию архитектуры процессора;</li><li><b>Эстетика хакерской культуры</b> — умение поместить игру в QR-код служит чистым челленджем и поводом для обсуждений в сообществе.</li></ol><h2>Где посмотреть и запустить</h2><p>Сборник кода, QR-изображение и онлайн-демо доступны на <a href="https://github.com/donno2048/snake">странице проекта</a> на GitHub.</p><p>Там же — инструкции, как запустить локально (скрипты main.sh/main.bat) и как собрать свое QR-воплощение.</p>]]></content:encoded>
    </item>
    <item>
      <title>50 000 строк ассемблерного кода легендарной игры Elite для Commodore 64 слили в сеть</title>
      <link>https://tproger.ru/news/--50-000-strok-assemblernogo-koda-legendarnoj-igry-elite-dlya-commodore-64-slili-v-set</link>
      <comments>https://tproger.ru/news/--50-000-strok-assemblernogo-koda-legendarnoj-igry-elite-dlya-commodore-64-slili-v-set?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/--50-000-strok-assemblernogo-koda-legendarnoj-igry-elite-dlya-commodore-64-slili-v-set</guid>
      <description><![CDATA[<p>Исходный код легендарной игры Elite для Commodore 64 опубликован на GitHub: 50 000 строк ассемблера с комментариями и сборками для изучения</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/--50-000-strok-assemblernogo-koda-legendarnoj-igry-elite-dlya-commodore-64-slili-v-set">50 000 строк ассемблерного кода легендарной игры Elite для Commodore 64 слили в сеть</a>»</p>]]></description>
      <category><![CDATA[Ретро]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 17 Dec 2024 03:03:05 GMT</pubDate>
      <content:encoded><![CDATA[<p>Исходный код знаменитой игры Elite для Commodore 64 стал доступен всем желающим на GitHub.</p><p>Проект содержит 50 000 строк ассемблерного кода, который был тщательно задокументирован и прокомментирован для понимания работы игры под капотом.</p><h2>Что это за проект?</h2><p>Разработчик Мара Моксон, энтузиаст и исследователь классических игр, опубликовал исходники Elite, позволив тем самым не только изучить их, но и собрать полную рабочую версию игры для Commodore 64 на современных компьютерах.</p><p>Документация включает:</p><ul><li>Подробные комментарии к каждой строке кода.</li><li>Варианты сборок для NTSC и PAL версий игры.</li><li>Пояснения к структуре файлов и использованным техникам.</li></ul><h2>Почему это важно?</h2><p>Elite, впервые вышедшая в 1984 году, считается одной из величайших игр в истории, задавших стандарты для жанров космических симуляторов и открытого мира.</p><p>Для Commodore 64 игра вышла в 1985 году и использовала ассемблерный код, демонстрируя уникальные для своего времени технические решения.</p><p>Теперь разработчики, энтузиасты и любители ретро-игр могут изучить, как создавался этот шедевр, и даже создать свои модификации или порты.</p><figure><img src="https://media.tproger.ru/user-uploads/98945/2024-12-17/b8df9221-6b05-46f1-bb03-2afea94442dc.jpeg" alt="" /></figure><h2>Где найти код?</h2><p>Исходный код доступен на <a href="https://github.com/markmoxon/elite-source-code-commodore-64">GitHub</a>. Кроме того, проект сопровождается удобным <a href="https://elite.bbcelite.com/">сайтом</a> с визуализированным и более «читаемым» представлением исходников.</p><p>Этот релиз — редкая возможность заглянуть в историю и увидеть, как программисты 80-х справлялись с ограниченными ресурсами для создания одной из самых знаковых игр в индустрии.</p>]]></content:encoded>
    </item>
    <item>
      <title>Второй раунд битвы языков программирования в 2022 году</title>
      <link>https://tproger.ru/articles/vtoroj-raund-bitvy-jazykov-programmirovanija-v-2022-godu</link>
      <comments>https://tproger.ru/articles/vtoroj-raund-bitvy-jazykov-programmirovanija-v-2022-godu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Рафаил Агазода]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/vtoroj-raund-bitvy-jazykov-programmirovanija-v-2022-godu</guid>
      <description><![CDATA[<p>Начинается второй этап битвы за звание лучшего языка программирования в 2022 году. Теперь выбрать придётся между Go и Python, Assembler и C.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/vtoroj-raund-bitvy-jazykov-programmirovanija-v-2022-godu">Второй раунд битвы языков программирования в 2022 году</a>»</p>]]></description>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Лучший язык 2022]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 14 Dec 2022 08:00:26 GMT</pubDate>
      <content:encoded><![CDATA[<p>Завершился первый этап голосования за лучший язык программирования в 2022 году. Pascal уверенно обошёл Visual Basic и прошёл в следующий тур, а C# выиграл у С++ при отрыве всего в 50 голосов.</p><p>Результаты можно посмотреть <a href="https://tproger.ru/articles/nachalsja-battl-jazykov-programmirovanija-2022/">здесь</a>. Подпишитесь на тэг <a href="https://tproger.ru/tag/luchshij-jazyk-2022/">Лучший язык 2022</a> и следите за новыми раундами в личной ленте.</p><p>Сегодня в схватке столкнутся:</p><ul><li>Go и Python;</li><li>Assembler и C.</li></ul><figure><img src="https://media.tproger.ru/uploads/2022/12/battle_table-1.png" alt="" /></figure><p>Голосование по этим языкам программирования продлится до 15 декабря 2022 года. Опросы будут закрыты в 11:00 по МСК.</p>]]></content:encoded>
    </item>
    <item>
      <title>Стартует батл языков программирования 2022</title>
      <link>https://tproger.ru/articles/startuet-batl-jazykov-programmirovanija-2022</link>
      <comments>https://tproger.ru/articles/startuet-batl-jazykov-programmirovanija-2022?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марина Александровна]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/startuet-batl-jazykov-programmirovanija-2022</guid>
      <description><![CDATA[<p>Батл на звание лучшего языка программирования 2022 уже не за горами. Давайте узнаем, какой ЯП наиболее популярен по версии Tproger!</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/startuet-batl-jazykov-programmirovanija-2022">Стартует батл языков программирования 2022</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[BASIC]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Pascal]]></category>
      <category><![CDATA[Лучший язык 2022]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 12 Dec 2022 08:00:40 GMT</pubDate>
      <content:encoded><![CDATA[<p>Предлагаем отвлечься от серьёзных рейтингов вроде <a href="https://tproger.ru/articles/luchshij-jazyk-programmirovanija-rejting-tiobe-2022/">TIOBE</a> или PYPL и выбрать лучший язык программирования 2022 по версии пользователей Tproger.</p><p>Правила батла по-прежнему просты:</p><ol><li>В батле участвует 16 языков программирования.</li><li>Ежедневно соревнуются две пары.</li><li>За любимый язык можно проголосовать в течение 24 часов.</li><li>Пары составляются рандомно, так что выбирайте язык, который субъективно нравится больше.</li><li>В финале мы определим тройку победителей.</li><li>Старт — 13 декабря, финал — 20 декабря.</li></ol><p>Примечание Забирайте эту запись в закладки, ведь именно в неё будут добавляться ссылки на последующие этапы голосования.</p><ul><li><a href="https://tproger.ru/articles/nachalsja-battl-jazykov-programmirovanija-2022/">Этап 1</a></li><li><a href="https://tproger.ru/articles/vtoroj-raund-bitvy-jazykov-programmirovanija-v-2022-godu/">Этап 2</a></li><li><a href="https://tproger.ru/articles/tretij-raund-bitvy-jazykov-programmirovanija-v-2022-godu/">Этап 3</a></li><li><a href="https://tproger.ru/articles/chetvjortyj-raund-bitvy-jazykov-programmirovanija-2022/">Этап 4</a></li><li><a href="https://tproger.ru/articles/pjatyj-raund-bitvy-jazykov-programmirovanija-2022/">Этап 5</a></li><li><a href="https://tproger.ru/articles/shestoj-raund-bitvy-jazykov-programmirovanija-2022/">Этап 6</a></li><li><a href="https://tproger.ru/articles/polufinal-bitvy-jazykov-programmirovanija-2022">Полуфинал</a></li><li><a href="https://tproger.ru/articles/final-bitvy-jazykov-programmirovanija-2022/">Финал</a></li><li><a href="https://tproger.ru/articles/battl-jazykov-programmirovanija-2022-zavershilsja-2/">Результаты</a></li></ul><p>Турнирная таблица:</p><figure><img src="https://media.tproger.ru/uploads/2022/12/Turnirnaja-tablica.png" alt="" /></figure><p>Старт уже завтра — 13 декабря в 11:00 МСК. Следите, участвуйте, голосуйте!</p>]]></content:encoded>
    </item>
    <item>
      <title>Начался баттл языков программирования 2021</title>
      <link>https://tproger.ru/articles/nachalsja-battl-jazykov-programmirovanija-2021</link>
      <comments>https://tproger.ru/articles/nachalsja-battl-jazykov-programmirovanija-2021?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марина Александровна]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/nachalsja-battl-jazykov-programmirovanija-2021</guid>
      <description><![CDATA[<p>Выбираем лучший язык программирования 2021 из представленных пар. За звание лучшего сражаются: C vs. PHP, TypeScript vs. Assembler.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/nachalsja-battl-jazykov-programmirovanija-2021">Начался баттл языков программирования 2021</a>»</p>]]></description>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Лучший язык 2021]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 14 Dec 2021 08:00:07 GMT</pubDate>
      <content:encoded><![CDATA[<p>Сегодня за звание лучшего языка программирования 2021 по версии Tproger сражаются следующие пары:</p><ul><li>C vs. PHP</li><li>TypeScript vs. Assembler</li></ul><figure><img src="https://media.tproger.ru/uploads/2021/12/frame_13__5_.png" alt="" /></figure><p>Выбирайте любимый язык, исходя из личных симпатий. Голосование завершится 15 декабря 2021 года в 11:00 по Москве.</p><p>Ознакомиться с анонсом можно <a href="https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-startuet-uzhe-zavtra/">здесь</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Баттл языков программирования 2021 стартует уже завтра</title>
      <link>https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-startuet-uzhe-zavtra</link>
      <comments>https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-startuet-uzhe-zavtra?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марина Александровна]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-startuet-uzhe-zavtra</guid>
      <description><![CDATA[<p>Отбросьте результаты исследований TIOBE, ведь в нашем баттле именно вы выбираете лучший язык программирования 2021.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-startuet-uzhe-zavtra">Баттл языков программирования 2021 стартует уже завтра</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[BASIC]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Pascal]]></category>
      <category><![CDATA[Лучший язык 2021]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 13 Dec 2021 08:12:38 GMT</pubDate>
      <content:encoded><![CDATA[<p>Лучший язык программирования в 2021 году — это Java или Python? Совсем недавно рейтинг TIOBE взбудоражил всё IT-сообщество, ведь именно Python потеснил извечных лидеров в виде Java и C.</p><p>Но давайте отвлечёмся от официальной статистики и узнаем, какие языки предпочитаете именно вы! Завтра стартует баттл языков программирования 2021. Правила просты:</p><ol><li>Всего участвует 16 языков программирования.</li><li>Каждый день соревнуются две пары.</li><li>На возможность проголосовать за любимый язык отводится 24 часа.</li><li>Пары составляются рандомно.</li><li>Выбирайте тот язык, который субъективно нравится вам больше.</li><li>В финале мы определим победителей — языки которые заняли первое, второе и третье место.</li><li>Старт — 14 декабря, финал — 21 декабря.</li></ol><p>Так выглядит изначальная турнирная таблица:</p><figure><img src="https://media.tproger.ru/uploads/2021/12/languages_battle_2021_announce.png" alt="" /></figure><p>А вот как мы <a href="https://tproger.ru/tag/toplang2020/">выбирали лучший язык программирования</a> в прошлом году.</p><p>Подписывайтесь на уведомления на сайте, чтобы быть в курсе лидеров и новых голосований.</p><p>Результаты баттла можно посмотреть по <a href="https://tproger.ru/articles/battl-jazykov-programmirovanija-2021-zavershilsja/">ссылке</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как компилятор преобразует код на C в Assembler?</title>
      <link>https://tproger.ru/video/kak-kompiljator-preobrazuet-kod-na-c-v-assembler</link>
      <comments>https://tproger.ru/video/kak-kompiljator-preobrazuet-kod-na-c-v-assembler?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Олег Борисенков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/video/kak-kompiljator-preobrazuet-kod-na-c-v-assembler</guid>
      <description><![CDATA[<p>Автор видео с ручкой и бумагой сравнивает программу на C и её ассемблерный вид на примере вывода чисел Фибоначчи, объясняя машинный код.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/video/kak-kompiljator-preobrazuet-kod-na-c-v-assembler">Как компилятор преобразует код на C в Assembler?</a>»</p>]]></description>
      <category><![CDATA[Компиляторы]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Видео]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 03 Jan 2021 09:12:27 GMT</pubDate>
      <content:encoded><![CDATA[<p>Автор видео, используя только ручку и бумагу, сравнивает код на C и скомпилированный в Assembler. Он делает это на примере программы, которая выводит на экран <a href="https://tproger.ru/problems/finding-fibonacci/">числа Фибоначчи</a>.</p><p>В комментариях подсказывают, что в реальности машинный код получается более оптимизированным. <a href="https://godbolt.org/z/7dYv58">По этой ссылке</a> вы найдете компилятор из языка Си в Assembler, который подсвечивает соответствующие друг другу строки программы на С и Assembler.</p><p>0:00 Как программа на C считает числа Фибоначчи</p><p>2:28 Как скомпилировать и дизассемблировать программу</p><p>3:20 Разбор машинного кода</p>]]></content:encoded>
    </item>
    <item>
      <title>Битва языков программирования 2020 продолжается!</title>
      <link>https://tproger.ru/articles/bitva-jazykov-programmirovanija-2020-prodolzhaetsja</link>
      <comments>https://tproger.ru/articles/bitva-jazykov-programmirovanija-2020-prodolzhaetsja?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Олег Борисенков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/bitva-jazykov-programmirovanija-2020-prodolzhaetsja</guid>
      <description><![CDATA[<p>Во втором дне голосования соревнуются две новые пары языков, а по итогам первого Swift обошёл PHP, а Kotlin немного не дотянул до Java.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/bitva-jazykov-programmirovanija-2020-prodolzhaetsja">Битва языков программирования 2020 продолжается!</a>»</p>]]></description>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Pascal]]></category>
      <category><![CDATA[Лучший язык 2020]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 15 Dec 2020 08:02:11 GMT</pubDate>
      <content:encoded><![CDATA[<p>Первый день голосования закончился. По его итогам Swift уверенно обошёл PHP, а Kotlin немного не дотянул до Java. Смотрите результаты <a href="https://tproger.ru/articles/nachalsja-battl-jazykov-programmirovanija-2020/">здесь</a>.</p><figure><img src="https://media.tproger.ru/uploads/2020/12/Frame-4-3.png" alt="" /></figure><p>Сегодня соревнуются следующие две пары языков: Assembler/Pascal и С++/Cobol. Помните, что мы не сравниваем языки объективно. Выбирайте тот, что вы любите.</p><p>Голосование закончится ровно через 24 часа — 16 декабря 2020 года в 11:00 по московскому времени.</p><p>Финальное голосование — <a href="https://tproger.ru/articles/final-battla-jazykov-programmirovanija-2020-uzhe-segodnja/">здесь</a>.</p><p>Включите уведомления в браузере, чтобы следить за ходом голосования.</p>]]></content:encoded>
    </item>
    <item>
      <title>Примите участие в баттле языков программирования 2020. Старт уже завтра!</title>
      <link>https://tproger.ru/articles/primite-uchastie-v-battle-jazykov-programmirovanija-2020-start-uzhe-zavtra</link>
      <comments>https://tproger.ru/articles/primite-uchastie-v-battle-jazykov-programmirovanija-2020-start-uzhe-zavtra?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Олег Борисенков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/primite-uchastie-v-battle-jazykov-programmirovanija-2020-start-uzhe-zavtra</guid>
      <description><![CDATA[<p>Голосование выяснит, какие языки подписчики любят больше всего, пока Java и язык Си меняются местами на вершине рейтинга TIOBE.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/primite-uchastie-v-battle-jazykov-programmirovanija-2020-start-uzhe-zavtra">Примите участие в баттле языков программирования 2020. Старт уже завтра!</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Pascal]]></category>
      <category><![CDATA[Лучший язык 2020]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 13 Dec 2020 08:00:30 GMT</pubDate>
      <content:encoded><![CDATA[<p>В то время как Java и язык Си меняются местами на вершине рейтинга TIOBE, мы решили выяснить, какие языки программирования, наши подписчики любят больше всего.</p><p>Завтра начинается баттл языков программирования 2020. Правила просты:</p><ul><li>В баттле участвуют 16 языков;</li><li>ежедневно соревнуются две пары;</li><li>на каждое голосование отводится 24 часа;</li><li>вы выбираете язык который субъективно нравится вам больше чем его оппонент;</li><li>пары подбираются случайно;</li><li>в результате мы определим победителей, занявших первое, второе и третье места;</li><li>Старт завтра — 14 декабря, финал — 21 декабря.</li></ul><p>Так выглядит изначальная турнирная таблица:</p><figure><img src="https://media.tproger.ru/uploads/2020/12/Frame-4.png" alt="" /></figure><p>Подписывайтесь на уведомления на сайте, чтобы быть в курсе текущих лидеров и новых голосований.</p>]]></content:encoded>
    </item>
    <item>
      <title>Выпущена версия DOOM, работающая только на mov-инструкциях</title>
      <link>https://tproger.ru/news/doom-movfuscated</link>
      <comments>https://tproger.ru/news/doom-movfuscated?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/doom-movfuscated</guid>
      <description><![CDATA[<p>Патч M/o/Vfuscator компилирует DOOM только с инструкцией mov в ассемблере, используя её тьюринг-полноту вместо условных операторов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/doom-movfuscated">Выпущена версия DOOM, работающая только на mov-инструкциях</a>»</p>]]></description>
      <category><![CDATA[Низкоуровневое программирование]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Чипокалипсис]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 25 Jan 2018 13:27:15 GMT</pubDate>
      <content:encoded><![CDATA[<p>Разработчики инструмента <a href="https://tproger.ru/articles/movfuscator/">M/o/Vfuscator</a> выпустили <a href="https://github.com/xoreaxeaxeax/movfuscator/tree/master/validation/doom">патч</a> для классической компьютерной игры DOOM, который позволяет скомпилировать игру без использования условных операторов и вообще каких-либо инструкций, кроме <a href="https://en.wikipedia.org/wiki/MOV_(x86_instruction)">mov</a> в языке ассемблера. Сделано это для доказательства работоспособности и применимости их инструмента. При этом не применяется никаких трюков с самомодифицирующимся кодом или подобных — всё работает честно.</p><h3>Как такое возможно?</h3><p>Оказывается, сама по себе инструкция mov <a href="https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B0_%D0%BF%D0%BE_%D0%A2%D1%8C%D1%8E%D1%80%D0%B8%D0%BD%D0%B3%D1%83">тьюринг-полная</a>, а значит, с её помощью можно запрограммировать любой алгоритм, как на классических языках.</p><p>Если коротко, то суть в том, как проводить «сравнения» и затем в зависимости от результата выполнять определённую команду. Допустим, мы хотим сравнить значения A и B. Помещаем их в регистры Ri и Rj. Мы это можем сделать, у нас есть mov. Затем выполняем хитрый код:</p><p>Здесь мы интерпретируем значения Ri и Rj (т.е. A и B) как адреса и записываем в них 0 и 1. Если значения были одинаковые, то и адрес будет одинаковый, и он перезапишется. В итоге в Rk будет 1, если A=B, и 0 в другом случае. Почему нам не важно, что было по адресам Ri и Rj — читайте в подробном разборе, для нас это сейчас не имеет значения.</p><p>Затем мы можем поместить по некоторому адресу N одну инструкцию, а в следующую ячейку памяти N+1 — другую. И выполнить ту, что по адресу N+Rk. Вот мы и получили аналог условного выполнения инструкций, но используя только mov. Осталось только перевести весь код в такую форму, а в самом конце добавить безусловный переход на начало программы.</p><p>Более детально изучить, как это работает, можно по <a href="https://www.youtube.com/watch?v=R7EEoWg6Ekk">презентации</a>, <a href="https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf">слайдам</a> или текстовому описанию в PDF.</p><h3>Зачем это нужно?</h3><p>В некотором роде подобные схемы уже реализуются в <a href="https://ru.wikipedia.org/wiki/RISC">RISC-архитектуре</a>. Иначе говоря, идея не новая и позволяет выпускать более простые компиляторы и процессоры, которые по этой причине могут работать быстрее и быть дешевле. Кроме того, такой код защищён от <a href="https://tproger.ru/articles/meltdown-spectre-vulnerabilities-overview/">недавних уязвимостей в процессорах</a> просто по определению, т.к. в нём нет спекулятивного выполнения инструкций.</p><p>Для авторов M/o/Vfuscator сборка DOOM только через mov-инструкции нужна для доказательства работоспособности их метода. Работает, правда, всё очень долго — один кадр рендерится около 7 часов. Но в данном случае главное, что вообще работает.</p>]]></content:encoded>
    </item>
    <item>
      <title>Курс «Программирование с нуля»</title>
      <link>https://tproger.ru/video/programming-from-scratch</link>
      <comments>https://tproger.ru/video/programming-from-scratch?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марьяна Шабанова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/video/programming-from-scratch</guid>
      <description><![CDATA[<p>Курс для новичков объясняет основы программирования на ассемблере без опыта программирования и углублённых знаний математики: от информации до операторов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/video/programming-from-scratch">Курс «Программирование с нуля»</a>»</p>]]></description>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Видео]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 04 Oct 2017 12:42:34 GMT</pubDate>
      <content:encoded><![CDATA[<p>Русскоязычный курс для абсолютных новичков, рассказывающий об основах программирования на примере языка ассемблера.</p><p>Данный курс это авторская программа «Школы Программистов», целью которой является изложить самые базовые понятия из мира программирования в доступном и структурированном виде.</p><p>Для этого курса не нужны предварительные углублённые знания в математике или опыт программирования. Курс начинается с таких понятий, как информация в целом, затем следует часть введения в ассемблер и углубление знаний до процедур и операторов в ассемблере.</p>]]></content:encoded>
    </item>
    <item>
      <title>Курс «Основы программирования встраиваемых систем»</title>
      <link>https://tproger.ru/video/embedded-systems</link>
      <comments>https://tproger.ru/video/embedded-systems?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дмитрий Баранчук]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/video/embedded-systems</guid>
      <description><![CDATA[<p>Русскоязычный курс знакомит с микроконтроллерами и их применением в часах, роботах, автомобилях, медицинских приборах и системах умного дома.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/video/embedded-systems">Курс «Основы программирования встраиваемых систем»</a>»</p>]]></description>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Видео]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 29 Sep 2017 19:06:36 GMT</pubDate>
      <content:encoded><![CDATA[<p>Русскоязычный курс, открывающий своим слушателям удивительный мир микроконтроллеров. Среди окружающих нас приборов все сложнее встретить такие, в которых их нет. Часы и светофоры, системы освещения, электронные игрушки и роботы, телевизоры и пылесосы, микроволновки и чайники, автомобили и медицинские приборы, охранные системы и умные дома — все это оживает благодаря микроконтроллерам.</p><p>В курсе будут рассмотрены следующие темы:</p><ul><li>отличия микроконтроллеров от традиционных компьютеров;</li><li>обзор популярных семейств микроконтроллеров (ARM, AVR, MSP430 и др.) , их возможностей, а также проектов на их основе;</li><li>настройка среды разработчика и написание программ на Си и Ассемблер;</li><li>обзор периферийных интерфейсов и протоколов;</li><li>ввод/вывод общего назначения и подключение различных внешних устройств;</li><li>работа с прерываниями и таймерами;</li><li>сведения о начальной загрузке и инициализации контроллера.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Компилятор Си в одну инструкцию: обзор инструмента M/o/Vfuscator</title>
      <link>https://tproger.ru/articles/movfuscator</link>
      <comments>https://tproger.ru/articles/movfuscator?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Саша Ушатинская]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/movfuscator</guid>
      <description><![CDATA[<p>Инструмент собирает программы только из инструкций mov, ориентирован на язык Си и архитектуру x86, но настраивается под другие языки и архитектуры.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/movfuscator">Компилятор Си в одну инструкцию: обзор инструмента M/o/Vfuscator</a>»</p>]]></description>
      <category><![CDATA[Низкоуровневое программирование]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 30 Mar 2017 13:30:58 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://github.com/xoreaxeaxeax/movfuscator">M/o/Vfuscator</a> компилирует программы в инструкции mov, и только в них. Инструмент ориентирован на язык Си и архитектуру процессора x86, но адаптивен и легко настраивается под другие языки и архитектуры.</p><h3>Демонстрация</h3><p>Компиляция функции, вычисляющей простые числа, с помощью M/o/Vfuscator в сравнении с GCC:</p><h4>Язык Ассемблера</h4><figure><img src="https://media.tproger.ru/uploads/2017/03/1-5.png" alt="" /></figure><p>GCC</p><figure><img src="https://media.tproger.ru/uploads/2017/03/2-4.png" alt="" /></figure><p>M/o/Vfuscator</p><h4>Граф потока управления</h4><figure><img src="https://media.tproger.ru/uploads/2017/03/3-2.png" alt="" /></figure><p>GCC</p><figure><img src="https://media.tproger.ru/uploads/2017/03/4-3.png" alt="" /></figure><p>M/o/Vfuscator</p><h4>M/o/Vfuscator в действии</h4><figure><img src="https://media.tproger.ru/uploads/2017/03/5.gif" alt="" /><figcaption>movcc prime.c -o prime</figcaption></figure><h4>Пример поинтереснее</h4><figure><img src="https://media.tproger.ru/uploads/2017/03/6.gif" alt="" /><figcaption>movcc nibbles.c -o nibbles -lncurses</figcaption></figure><h3>Сборка</h3><p>M/o/Vfuscator использует LCC в качестве препроцессора. Предлагаемый скрипт сборки автоматически загружает LCC, настраивает его конфигурацию для MOV и собирает M/o/Vfuscator.</p><p>Если вы проводите сборку на 64-битной системе, убедитесь, что у вас есть доступ к 32-битной стандартной библиотеке (например, apt-get install libc6-dev-i386 или yum install glibc-devel.i686).</p><h3>Тестирование</h3><p>Проверьте, что сборка произошла корректно, с помощью следующего скрипта:</p><h3>Использование</h3><p>Компилируйте программы как обычно.</p><p>Всю остальную необходимую информацию <a href="https://github.com/xoreaxeaxeax/movfuscator">можно найти</a> в репозитории проекта на GitHub.</p>]]></content:encoded>
    </item>
    <item>
      <title>Руководство по созданию ядра для x86-системы. Часть 2. Система ввода / вывода</title>
      <link>https://tproger.ru/translations/lets-write-a-kernel-2</link>
      <comments>https://tproger.ru/translations/lets-write-a-kernel-2?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Иван Бирюков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/lets-write-a-kernel-2</guid>
      <description><![CDATA[<p>Arjun Sreedharan подключает к ядру драйвер клавиатуры, который считывает символы a–z и 0–9 и выводит их на экран через порты ввода-вывода x86.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/lets-write-a-kernel-2">Руководство по созданию ядра для x86-системы. Часть 2. Система ввода / вывода</a>»</p>]]></description>
      <category><![CDATA[Низкоуровневое программирование]]></category>
      <category><![CDATA[Операционные системы]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 18 Dec 2016 18:15:52 GMT</pubDate>
      <content:encoded><![CDATA[<p>Рассказывает Arjun Sreedharan</p><p>В <a href="https://tproger.ru/translations/lets-write-a-kernel-1/">прошлой статье</a> я писал о том, как создать простейшее x86-ядро, использующее GRUB, работающее в защищённом режиме и выводящее на экран строку. В этот раз мы подключим к ядру драйвер клавиатуры, который может считывать символы a–z и 0–9 с клавиатуры и выводить их на экран. Весь используемый код можно найти <a href="http://github.com/arjun024/mkeykernel">на GitHub</a>.</p><figure><img src="https://media.tproger.ru/uploads/2016/12/tumblr_inline_ncyxrtFyJm1rivrqc.jpg" alt="" /></figure><p>Мы общаемся с устройствами ввода / вывода, используя <b>I/O-порты</b>. Эти порты — просто определённые адреса на шине ввода / вывода x86-системы. Операции чтения / записи на этих портах обрабатываются специальными инструкциями, встроенными в процессор.</p><h3>Чтение из портов и запись в них</h3><p>Доступ к портам I/O можно получить, используя инструкции in и out, являющиеся частью набора инструкций x86.</p><p>В read_port номер порта принимается как аргумент. Когда компилятор вызывает вашу функцию, он пушит все её аргументы в стек. Аргумент копируется в регистр edx по указателю на стек. Регистр dx — это младшие 16 бит edx. Инструкция in читает из порта, номер которого хранится в dx, и помещает результат в al. Регистр al — это младшие 8 бит eax. Если вы помните, чему вас учили, то знаете, что возвращаемые функциями значения передаются через регистр eax register. Таким образом, read_port обеспечивает чтение из I/O-портов.</p><p>write_port очень похожа. Мы принимаем два аргумента: номер порта и данные для записи. Инструкция out записывает данные в указанный порт.</p><h3>Прерывания</h3><p>Теперь, прежде чем мы продолжим писать какой-либо драйвер устройства, давайте разберемся, как процессор узнаёт о том, что устройство совершило действие.</p><p>Самое простое решение — это <a href="https://en.wikipedia.org/wiki/Polling_(computer_science)">поллинг</a>, постоянная проверка состояния устройства. По очевидным причинам это не самое практичное решение. Тут в дело вступают прерывания. Прерывание — это сигнал, посылаемый процессору аппаратным или системным обеспечением, который оповещает о событии. Используя прерывания, мы можем действовать только тогда, когда возникает интересующее нас прерывание.</p><p>Устройство, называемое <a href="https://ru.wikipedia.org/wiki/Контроллер_прерываний">контроллером прерываний</a> (Programmable Interrupt Controller, PIC), отвечает за обработку аппаратных прерываний и отправку их соответствующим системным прерываниям.</p><p>Когда на аппаратном обеспечении происходит какое-то событие, оно отправляет сигнал, называемый запросом прерывания, по свому специальному каналу на контроллер прерываний. Контроллер преобразует запрос в системное прерывание и отправляет его в процессор, где им занимается ядро.</p><p>Если бы у нас не было контроллера прерываний, то нам пришлось бы постоянно опрашивать все устройства на наличие произошедших событий.</p><p>Рассмотрим случай с клавиатурой. Она работает через I/O-порты 0x60 и 0x64. Порт 0x60 передаёт данные (о нажатой клавише), а порт 0x64 — состояние. Однако нужно знать наверняка, когда и из какого порта читать данные.</p><p>Для этого отлично подходят прерывания. Когда происходит нажатие клавиши, клавиатура посылает сигнал на контроллер прерываний по линии IRQ1. Контроллер обладает значением offset, полученным во время его инициализации. Он добавляет номер входной линии к этому offset и получает число прерывания. Затем процессор обращается к специальной структуре данных, называющейся дескрипторной таблицей прерываний (Interrupt Descriptor Table, IDT), для передачи обработчику прерываний адреса, соответствующего числу прерывания.</p><p>После этого запускается код, расположенный по этому адресу, и обрабатывает исключение.</p><h3>Настраиваем IDT</h3><p>Мы реализуем IDT как массив структур IDT_entry. Мы обсудим то, как прерывание клавиатуры привязано к своему обработчику, позже. Сперва посмотрим, как работают контроллеры прерываний.</p><p>Современные x86-системы имеют два контроллера прерываний по 8 входных линий. Назовём их PIC1 и PIC2. PIC1 получает сигналы с IRQ0 до IRQ7, а PIC2 — с IRQ8 до IRQ15. PIC1 использует порт 0x20 для команд и 0x21 — для данных. PIC2 использует порт 0xA0 для команд и 0xA1 — для данных.</p><p>Контроллеры инициализируются 8-битными инициализирующими командными словами (Initialization command words, ICW). Подробный синтаксис этих команд можно изучить <a href="http://stanislavs.org/helppc/8259.html">здесь</a>.</p><p>В защищённом режиме первой командой, которую вы должны передать двум контроллерам прерываний, является инициализирующая команда <b>ICW1</b> (0x11). Эта команда заставляет контроллер ждать поступления ещё трёх инициализирующих слов на порт данных.</p><p>Эти команды сообщают контроллерам следующее:</p><ul><li>сдвиг (ICW2);</li><li>состояние подключения (master/slave) (ICW3);</li><li>дополнительную информацию об окружении (ICW4).</li></ul><p>Вторая инициализирующая команда — это ICW2, которая записывает в порты данных каждого контроллера его сдвиг.</p><p>Контроллеры допускают каскадирование выводов и вводов, что настраивается командой ICW3, но мы не будем его использовать, поэтому установим все значения в ноль.</p><p>ICW4 устанавливает дополнительные параметры окружения. Мы  заполним младший бит, чтобы сказать контроллерам, что мы работаем в режиме 80×86.</p><p>Та-дам! Контроллеры прерываний инициализированы!</p><p>У каждого контроллера есть внутренний 8-битный регистр, называющийся регистр масок прерывания (Interrupt Mask Register, IMR). Этот регистр хранит битмэп линий IRQ, идущих в контроллер. Если бит установлен, контроллер игнорирует запрос. Это означает, что мы можем включать и выключать любую линию IRQ, меняя соответствующее значение в IMR. Чтение из порта данных возвращает значение из IMR, а запись — задаёт это значение. В нашем коде мы отключаем все линии IRQ, чтобы позже включить ту, что соответствует клавиатуре.</p><p>Если линии IRQ включены, наши контроллеры могут получать идущие по ним сигналы и преобразовывать их в числа прерываний, добавляя сдвиг. Теперь нам нужно найти IDT такую, чтобы число прерывания для клавиатуры было привязано к адресу обработчика событий клавиатуры, который мы напишем.</p><p>Какое число прерывания должно соответствовать обработчику событий клавиатуры?</p><p>Клавиатура использует IRQ<b>1</b>. Это линия ввода 1 контроллера PIC1. Его сдвиг равен 0x20. Для получения числа прерывания сложим 1 <b>+</b> 0x20 и получим 0x21. Таким образом, адрес обработчика событий должен быть связан с прерыванием 0x21 в IDT.</p><p>Теперь нам нужно определить IDT для прерывания 0x21. Мы привяжем это прерывание к функции keyboard_handler, которую запишем в ассемблерном файле.</p><p>Каждое значение в IDT состоит из 64 битов. В значении IDT для прерывания мы не храним адрес функции-обработчика целиком, а делим его на 2 части по 16 бит. Младшие биты хранятся в первых 16 битах значения IDT, а старшие 16 битов — в последних. Это сделано в целях совместимости с 286. Да, такие костыли от Intel можно встретить часто!</p><p>В значении IDT мы также должны задать тип — это нужно для того, чтобы поймать исключение. Нам также нужно передать коду ядра смещение. GRUB создаст для нас <a href="https://ru.wikipedia.org/wiki/GDT">глобальную таблицу дескрипторов</a>, каждое значение которое занимает 8 байт. Дескриптор кода ядра — это второй сегмент, поэтому его сдвиг равен 0x08. Окно прерывания равно 0x8e. Оставшиеся посередине 8 бит должны быть заполнены нулями. Таким образом, мы заполнили значение IDT в соответствии с прерыванием клавиатуры.</p><p>После того, как мы закончили все махинации с IDT, мы сообщаем процессору её адрес, используя инструкцию lidt, принимающую один операнд, который должен быть указателем на структуру дескрипторов, описывающую IDT.</p><p>Дескриптор достаточно прост. Он содержит размер IDT в байтах и её адрес. Для хранения значений я использовал массив, но вы можете воспользоваться структурой.</p><p>У нас есть указатель в переменной idt_ptr, который мы передаём в lidt, используя функцию load_idt().</p><p>Кроме того, функция load_idt() включает прерывания, используя инструкцию sti.</p><p>Когда IDT настроена, мы можем включить линию IRQ клавиатуры, используя маску прерываний, о которой мы говорили ранее.</p><h3>Функция обработки прерываний клавиатуры</h3><p>Итак, наши прерывания клавиатуры привязаны к функции keyboard_handler через значение IDT для прерывания 0x21. Каждый раз, когда мы нажимаем клавишу, мы можем быть уверены, что функция будет вызвана.</p><p>Эта функция просто вызывает другую функцию, написанную на Си, и возвращает значение, используя класс инструкций iret. Мы могли бы написать здесь весь необходимый код, но на Си писать безусловно приятнее. iret/iretd используются вместо ret при работе с прерываниями.</p><p>Сперва мы отправляем сигнал <b>EOI</b> (конец прерывания), записывая его в порт команд контроллера. Только после этого контроллер принимает следующие прерывания. Нам нужно читать два порта — порт данных 0x60 и порт команд / данных 0x64.</p><p>Сперва мы читаем порт 0x64 для получения состояния. Если младший бит состояния равен 0, то буфер пуст, и данных для чтения нет. В обратном случае мы читаем порт данных 0x60. Этот порт даёт нам код каждой нажатой клавиши. Мы используем простой массив символов в файле keyboard_map.h для связывания кодов и символов.</p><p>В этой статье мы обрабатываем только строчные буквы и цифры. Конечно, можно настроить и обработку других клавиш, а также их сочетаний.</p><p>Вы можете собрать ядро и запустить его на реальной машине или в эмуляторе (QEMU) так же, как и в прошлой статье.</p><p>Печатайте!</p><figure><img src="https://media.tproger.ru/uploads/2016/12/tumblr_inline_ncy1p0kSGj1rivrqc.png" alt="" /></figure>]]></content:encoded>
    </item>
    <item>
      <title>Руководство по созданию ядра для x86-системы. Часть 1. Просто ядро</title>
      <link>https://tproger.ru/translations/lets-write-a-kernel-1</link>
      <comments>https://tproger.ru/translations/lets-write-a-kernel-1?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Иван Бирюков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/lets-write-a-kernel-1</guid>
      <description><![CDATA[<p>Arjun Sreedharan показывает, как написать ядро, загружаемое бутлоадером GRUB, и объясняет, что происходит с регистрами процессора при старте x86.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/lets-write-a-kernel-1">Руководство по созданию ядра для x86-системы. Часть 1. Просто ядро</a>»</p>]]></description>
      <category><![CDATA[Низкоуровневое программирование]]></category>
      <category><![CDATA[Операционные системы]]></category>
      <category><![CDATA[Язык Си]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 05 Dec 2016 18:50:15 GMT</pubDate>
      <content:encoded><![CDATA[<p>Рассказывает Arjun Sreedharan</p><p>Давайте напишем простое ядро, которое можно загрузить при помощи бутлоадера GRUB x86-системы. Это ядро будет отображать сообщение на экране и ждать.</p><figure><img src="https://media.tproger.ru/uploads/2016/12/one-does-not-kernel.jpg" alt="" /></figure><h3>Как загружается x86-система?</h3><p>Прежде чем мы начнём писать ядро, давайте разберёмся, как система загружается и передаёт управление ядру.</p><p>В большей части регистров процессора при запуске уже находятся определённые значения. Регистр, указывающий на адрес инструкций (Instruction Pointer, EIP), хранит в себе адрес памяти, по которому лежит исполняемая процессором инструкция. EIP по умолчанию равен <b>0xFFFFFFF0</b>. Таким образом, x86-процессоры на аппаратном уровне начинают работу с адреса 0xFFFFFFF0. На самом деле это — последние 16 байт 32-битного адресного пространства. Этот адрес называется вектором перезагрузки (reset vector).</p><p>Теперь карта памяти чипсета гарантирует, что 0xFFFFFFF0 принадлежит определённой части BIOS, не RAM. В это время BIOS копирует себя в RAM для более быстрого доступа. Адрес 0xFFFFFFF0 будет содержать лишь инструкцию перехода на адрес в памяти, где хранится копия BIOS.</p><p>Так начинается исполнение кода BIOS. Сперва BIOS ищет устройство, с которого можно загрузиться, в предустановленном порядке. Ищется магическое число, определяющее, является ли устройство загрузочным  (511-ый и 512-ый байты первого сектора должны равняться <b>0xAA55</b>).</p><p>Когда BIOS находит загрузочное устройство, она копирует содержимое первого сектора устройства в RAM, начиная с физического адреса <b>0x7c00</b>; затем переходит на адрес и исполняет загруженный код. Этот код называется бутлоадером.</p><p>Бутлоадер загружает ядро по физическому адресу <b>0x100000</b>. Этот адрес используется как стартовый во всех больших ядрах на x86-системах.</p><p>Все x86-процессоры начинают работу в простом 16-битном режиме, называющимся <b>реальным режимом</b>. Бутлоадер GRUB переключает режим в 32-битный <b>защищённый режим</b>, устанавливая нижний бит регистра CR0 в <b>1</b>. Таким образом, ядро загружается в 32-битном защищённом режиме.</p><p>Заметьте, что в случае с ядром Linux GRUB видит протоколы загрузки Linux и загружает ядро в реальном режиме. Ядро самостоятельно <a href="http://github.com/torvalds/linux/blob/master/arch/x86/boot/main.c#L181">переключается</a> в защищённый режим.</p><h3>Что нам нужно?</h3><ul><li>x86-компьютер;</li><li>Linux;</li><li><a href="http://www.nasm.us/">ассемблер NASM</a>;</li><li>gcc;</li><li>ld (GNU Linker);</li><li><a href="http://www.gnu.org/software/grub/">grub</a>;</li></ul><p>Исходники можно найти <a href="http://github.com/arjun024/mkernel">на GitHub</a>.</p><h3>Задаём точку входа на ассемблере</h3><p>Как бы не хотелось ограничиться одним Си, что-то придётся писать на ассемблере. Мы напишем на нём небольшой файл, который будет служить исходной точкой для нашего ядра. Всё, что он будет делать — вызывать внешнюю функцию, написанную на Си, и останавливать поток программы.</p><p>Как же нам сделать так, чтобы этот код обязательно был именно исходной точкой?</p><p>Мы будем использовать скрипт-линковщик, который соединяет объектные файлы для создания конечного исполняемого файла. В этом скрипте мы явно укажем, что хотим загрузить данные по адресу 0x100000.</p><p>Вот код на ассемблере:</p><p>Первая инструкция, bits 32, не является x86-ассемблерной инструкцией. Это директива ассемблеру NASM, задающая генерацию кода для процессора, работающего в 32-битном режиме. В нашем случае это не обязательно, но вообще полезно.</p><p>Со второй строки начинается секция с кодом.</p><p>global — это ещё одна директива NASM, делающая символы исходного кода глобальными. Таким образом, линковщик знает, где находится символ start — наша точка входа.</p><p>kmain — это функция, которая будет определена в файле kernel.c. extern значит, что функция объявлена где-то в другом месте.</p><p>Затем идёт функция start, вызывающая функцию kmain и останавливающая процессор инструкцией hlt. Именно поэтому мы заранее отключаем прерывания инструкцией cli.</p><p>В идеале нам нужно выделить немного памяти и указать на неё указателем стека (esp). Однако, похоже, что GRUB уже сделал это за нас. Тем не менее, вы всё равно выделим немного места в секции BSS и переместим на её начало указатель стека. Мы используем инструкцию resb, которая резервирует указанное число байт. Сразу перед вызовом kmain указатель стека (esp) устанавливается на нужное место инструкцией mov.</p><h3>Ядро на Си</h3><p>В kernel.asm мы совершили вызов функции kmain(). Таким образом, наш “сишный” код должен начать исполнение с kmain():</p><p>Всё, что сделает наше ядро — очистит экран и выведет строку “my first kernel”.</p><p>Сперва мы создаём указатель vidptr, который указывает на адрес <b>0xb8000</b>. С этого адреса в защищённом режиме начинается “видеопамять”. Для вывода текста на экран мы резервируем 25 строк по 80 ASCII-символов, начиная с 0xb8000.</p><p>Каждый символ отображается не привычными 8 битами, а 16. В первом байте хранится сам символ, а во втором — attribute-byte. Он описывает форматирование символа, например, его цвет.</p><p>Для вывода символа s зелёного цвета на чёрном фоне мы запишем этот символ в первый байт и значение 0x02 во второй. 0 означает чёрный фон, 2 — зелёный цвет текста.</p><p>Вот таблица цветов:</p><p>В нашем ядре мы будем использовать светло-серый текст на чёрном фоне, поэтому наш байт-атрибут будет иметь значение 0x07.</p><p>В первом цикле программа выводит пустой символ по всей зоне 80×25. Это очистит экран. В следующем цикле в “видеопамять” записываются символы из нуль-терминированной строки “my first kernel” с байтом-атрибутом, равным 0x07. Это выведет строку на экран.</p><h3>Связующая часть</h3><p>Мы должны собрать kernel.asm в объектный файл, используя NASM; затем при помощи GCC скомпилировать kernel.c в ещё один объектный файл. Затем их нужно присоединить к исполняемому загрузочному ядру.</p><p>Для этого мы будем использовать связывающий скрипт, который передаётся ld в качестве аргумента.</p><p>Сперва мы зададим формат вывода как 32-битный <a href="http://elinux.org/Executable_and_Linkable_Format_(ELF)">Executable and Linkable Format</a> (ELF). ELF — это стандарный формат бинарных файлов Unix-систем архитектуры x86. <b>ENTRY</b> принимает один аргумент, определяющий имя символа, являющегося точкой входа. <b>SECTIONS</b> — это самая важная часть. В ней определяется разметка нашего исполняемого файла. Мы определяем, как должны соединяться разные секции и где их разместить.</p><p>В скобках после SECTIONS точка (.) отображает счётчик положения, по умолчанию равный 0x0. Его можно изменить, что мы и делаем.</p><p>Смотрим на следующую строку: .text : { *(.text) }. Звёздочка (*) — это специальный символ, совпадающий с любым именем файла. Выражение *(.text) означает все секции .text из всех входных файлов.</p><p>Таким образом, линковщик соединяет все секции кода объектных файлов в одну секцию исполняемого файла по адресу в счётчике положения (0x100000). После этого значение счётчика станет равным 0x100000 + размер полученной секции.</p><p>Аналогично всё происходит и с другим секциями.</p><h3>Grub и Multiboot</h3><p>Теперь все файлы готовы к созданию ядра. Но остался ещё один шаг.</p><p>Существует стандарт загрузки x86-ядер с использованием бутлоадера, называющийся <b>Multiboot specification</b>. GRUB загрузит наше ядро, только если оно удовлетворяет <a href="http://www.gnu.org/software/grub/manual/multiboot/multiboot.html">этим спецификациям</a>.</p><p>Следуя им, ядро должно содержать заголовок в своих первых 8 килобайтах. Кроме того, этот заголовок должен содержать 3 поля, являющихся 4 байтами:</p><ul><li><b>магическое</b> поле: содержит магическое число <b>0x1BADB002</b> для идентификации ядра.</li><li>поле <b>flags</b>: нам оно не нужно, установим в ноль.</li><li>поле <b>checksum</b>: если сложить его с предыдущими двумя, должен получиться ноль.</li></ul><p>Наш kernel.asm станет таким:</p><h3>Строим ядро</h3><p>Теперь мы создадим объектные файлы из kernel.asm и kernel.c и свяжем их, используя наш скрипт.</p><p>Эта строка запустит ассемблер для создания объектного файла kasm.o в формате ELF-32.</p><p>Опция “-c” гарантирует, что после компиляции не произойдёт скрытого линкования.</p><p>Это запустит линковщик с нашим скриптом и создаст исполняемый файл, называющийся <b>kernel</b>.</p><h3>Настраиваем grub и запускаем ядро</h3><p>GRUB требует, чтобы имя ядра удовлетворяло шаблону kernel-&lt;version&gt;. Поэтому переименуйте ядро. Своё я назвал kernel-701.</p><p>Теперь поместите его в директорию <b>/boot</b>. Для этого понадобятся права суперпользователя.</p><p>В конфигурационном файле GRUB grub.cfg добавьте следующее:</p><p>Не забудьте убрать директиву hiddenmenu, если она есть.</p><p>Перезагрузите компьютер, и вы увидите список ядер с вашим в том числе. Выберите его, и вы увидите:</p><figure><img src="https://media.tproger.ru/uploads/2016/12/mkernel.png" alt="" /></figure><p>Это ваше ядро! В <a href="https://tproger.ru/translations/lets-write-a-kernel-1/">следующей части</a> добавим систему ввода / вывода.</p><h3>P.S.</h3><ul><li>Для любых фокусов с ядром лучше использовать виртуальную машину.</li><li>Для запуска ядра в <b>grub2 </b>конфиг должен выглядеть так:menuentry 'kernel 7001' {tset root='hd0,msdos1'tmultiboot /boot/kernel-7001 ro}</li><li>если вы хотите использовать эмулятор qemu, используйте:qemu-system-i386 -kernel kernel</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>На GitHub выложили тетрис, целиком помещающийся в загрузочном секторе</title>
      <link>https://tproger.ru/news/tetros-on-mbr</link>
      <comments>https://tproger.ru/news/tetros-on-mbr?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Лапа]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/tetros-on-mbr</guid>
      <description><![CDATA[<p>Клон Tetris занимает 446 байт и умещается в 512-байтном загрузочном секторе MBR, поэтому запускается сам, без всякой операционной системы.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/tetros-on-mbr">На GitHub выложили тетрис, целиком помещающийся в загрузочном секторе</a>»</p>]]></description>
      <category><![CDATA[Красивый хак]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 05 Oct 2016 18:31:52 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://github.com/daniel-e/tetros">TetrOS</a> — клон знаменитого Tetris, написанный на ассемблере. Он целиком вмещается в 512 байт загрузочного сектора (ему требуется всего 446 байт места, это как раз максимальный размер загрузчика в <a href="https://ru.wikipedia.org/wiki/%D0%93%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BE%D1%87%D0%BD%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C">MBR</a>).</p><p>MBR — раздел, содержащий код и данные, необходимые для последующей загрузки операционной системы и расположенные в первых физических секторах. Самые первые 446 байт диска отдаются под код загрузчика. Именно в это место и записывается TetrOS.</p><p>Естественно, из-за таких свойств он загружается перед любой операционной системой — никакой ОС ему не требуется, он работает сам. Да-да, вы не ослышались, TetrOS — сам себе загрузчик.</p><p>Вот так это выглядит на экране:</p><p>А исходник на загрузочном секторе выглядит так:</p><figure><img src="https://media.tproger.ru/uploads/2016/10/code.png" alt="" /></figure><p>И да, это весь исходник. Вы же помните, что он весит всего 446 байт?</p><p>Можно запустить эту «чудо-операционную систему» под qemu или даже по-настоящему установить на загрузочный раздел диска или флешки.</p><h3>Запуск</h3><p>qemu</p><p>Просто установите qemu:</p><p>sudo apt-get install qemu</p><p>и запустите:</p><p>make run</p><h3>Загрузка на флешку</h3><p>Скопируйте образ на флешку. Допустим, если флешка подмонтирована как /dev/sde, вам понадобится выполнить следующую команду, чтобы записать на ее загрузочный сектор TetrOS:</p><p>sudo dd if=tetros.img of=/dev/sde</p><h3>Описание игры</h3><p>Разработчик сумел всего в 512 байт памяти впихнуть не самый скучный дизайн. У каждого кирпичика в игре есть свой цвет, управление производится кнопками, в случае поражения игра завершается, кирпичики генерируются случайным образом… BolgenOS и рядом не стояла!</p><p>К несчастью, из-за размера от некоторых фич пришлось отказаться. В игре нет подсчета очков, рестарта игры без перезагрузки и отображения того, каким будет следующий кирпичик.</p><p>Игра написана на nasm, и ее можно собрать самостоятельно. Устанавливаем nasm:</p><p>sudo apt-get install nasm</p><p>Собираем с помощью команды make. На выходе вы получите файл tetros.img.</p><h3>Аналоги</h3><p>Это не единственный проект, умещающий какую-либо классическую игру в один загрузочный сектор. Вот, например:</p><ul><li><a href="https://github.com/dbittman/bootris">Bootris</a></li><li><a href="https://github.com/Shikhin/tetranglix">Tetranglix</a></li><li><a href="http://olivier.poudade.free.fr/src/BootChess.asm">BootChess</a></li><li><a href="https://github.com/programble/tetrasm">Tetrasm</a></li></ul>]]></content:encoded>
    </item>
    <item>
      <title>В Сети появилась серия статей-руководств по созданию собственной ОС на ассемблере и Rust</title>
      <link>https://tproger.ru/articles/os-creation-series</link>
      <comments>https://tproger.ru/articles/os-creation-series?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Иван Бирюков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/os-creation-series</guid>
      <description><![CDATA[<p>В блоге Филиппа Опперманна разобрана разработка 64-битной операционной системы: первые части на ассемблере, дальше Rust. Исходники доступны на GitHub.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/os-creation-series">В Сети появилась серия статей-руководств по созданию собственной ОС на ассемблере и Rust</a>»</p>]]></description>
      <category><![CDATA[Низкоуровневое программирование]]></category>
      <category><![CDATA[Операционные системы]]></category>
      <category><![CDATA[Обучение программированию]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 23 Aug 2016 18:33:23 GMT</pubDate>
      <content:encoded><![CDATA[<p>Предлагаем вашему вниманию серию англоязычных статей, опубликованную в <a href="http://os.phil-opp.com">блоге Филиппа Опперманна.</a> В ней подробно разбирается процесс разработки собственной 64-битной ОС на ассемблере и <a href="https://www.rust-lang.org/en-US/">Rust</a>. Серия пополняется, но на основе уже написанных статей можно написать достаточно функциональную операционную систему.</p><p>Разработка ведётся на Linux, весь исходный код доступен на <a href="https://github.com/phil-opp/blog_os">GitHub</a>. В первых двух статьях автор использует ассемблер для написания ядра, после этого — Rust.</p><p>Статьи написаны простым, понятным даже начинающим программистам языком, все термины либо объясняются в статье, либо снабжены ссылками на другие Интернет-ресурсы.</p><p>Реализация этого проекта однозначно будет вам полезна: во-первых, вы сможете освоить или подтянуть знания по используемым в нём языкам программирования, а во-вторых, разберётесь в основных принципах работы операционной системы.</p><p>Итак, вот список статей:</p><ol><li><a href="http://os.phil-opp.com/multiboot-kernel.html">Пишем простое x86-ядро</a>.</li><li><a href="http://os.phil-opp.com/entering-longmode.html">Переход в 64-битный режим</a>.</li><li><a href="http://os.phil-opp.com/set-up-rust.html">Настройка Rust</a>.</li><li><a href="http://os.phil-opp.com/printing-to-screen.html">Настройка интерфейса вывода</a>.</li><li><a href="http://os.phil-opp.com/allocating-frames.html">Аллокатор фреймов</a>.</li><li><a href="http://os.phil-opp.com/modifying-page-tables.html">Таблицы страниц</a>.</li><li><a href="http://os.phil-opp.com/remap-the-kernel.html">«Ремап» ядра</a>.</li><li><a href="http://os.phil-opp.com/kernel-heap.html">Куча.</a></li><li><a href="http://os.phil-opp.com/catching-exceptions.html">Обработка исключений</a>.</li><li><a href="http://os.phil-opp.com/better-exception-messages.html">Сообщения об исключениях</a>.</li><li><a href="http://os.phil-opp.com/returning-from-exceptions.html">Возврат из исключений</a>.</li><li><a href="http://os.phil-opp.com/double-faults.html">Двойные ошибки (ошибки исключений)</a>.</li></ol><p>Серия продолжает пополняться, поэтому периодически сюда заглядывайте, мы будем дополнять вышеуказанный список.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как создавался редактор ассемблерного кода SASM</title>
      <link>https://tproger.ru/articles/how-sasm-was-created</link>
      <comments>https://tproger.ru/articles/how-sasm-was-created?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Типичный программист]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/how-sasm-was-created</guid>
      <description><![CDATA[<p>Дмитрий Манушин о разработке SASM — кроссплатформенной среды для NASM, MASM, GAS и FASM с подсветкой синтаксиса и отладчиком, основанной на Qt.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/how-sasm-was-created">Как создавался редактор ассемблерного кода SASM</a>»</p>]]></description>
      <category><![CDATA[Язык ассемблера]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 17 Apr 2015 15:18:52 GMT</pubDate>
      <content:encoded><![CDATA[<p>Рассказывает создатель SASM, Дмитрий Манушин</p><p>Здравствуйте! Хочу немного рассказать о разработке проекта SASM — среды разработки для языков ассемблера.</p><p>Чтобы сразу было понятно о чём речь:<br />Сайт: <a href="http://dman95.github.io/SASM/">http://dman95.github.io/SASM/</a><br />Репозиторий с кодом на GitHub: <a href="https://github.com/Dman95/SASM">https://github.com/Dman95/SASM</a></p><h2>Что это?</h2><p>SASM — простая кроссплатформенная (доступна на Windows и Linux, люди собирали и под Mac) среда разработки для языков ассемблера NASM, MASM, GAS, FASM с подсветкой синтаксиса и отладчиком. Программа работает «из коробки» и хорошо подойдет для начинающих изучение языка ассемблера. Основана на Qt. Распространяется по свободной лицензии GNU GPL v3.0.</p><h2>Идея</h2><p>На 1 курсе в моём университете проходил учебный курс «Архитектура и язык ассемблера», в котором мы изучали ассемблер NASM и сдавали задачи на нем в ejudge контестах. Привыкший к использованию IDE при программировании до этого, я был не очень рад собирать все в командной строке. Удобных на мой взгляд IDE для NASM не было. Универсальные решения типа Geany мне не очень нравились. Да и хотелось уже сделать что-нибудь большое и заодно выучить C++.<br />Итак, было решено написать свою IDE для NASM, в первую очередь для себя и может быть однокурсников.</p><h2>Реализация</h2><p>Опыта написания GUI у меня до этого не было, да и C++ я на тот момент не знал (в 1 семестре у нас был C). Решил всему учиться сразу при написании проекта. Много слышал про фреймворк Qt и написание на нем приложений с графическим пользовательским интерфейсом. Его и было решено выбрать для проекта.</p><p>Qt — бесплатный кроссплатформенный фреймворк, да и достаточно популярный, что немаловажно при изучении. К тому же в комплекте с ним идет очень удобная среда разработки Qt Creator и замечательная справка Qt Assistant (однако только на английском).</p><h3>Первые шаги</h3><p>В первый день почитал немного лекций 2 курса по C++. Затем, так как хотелось побыстрее начать, прочитал первые 100 страниц книги Бланшета, Саммерфилда «Программирование GUI на C++» о программировании с использованием Qt.</p><p>Сначала был написан просто текстовый редактор с логом построения и окнами ввода/вывода. Программа умела собирать код, который был в текстовом редакторе и запускать построенную программу, передавая ей ввод и получая её вывод (и для сборки, и для запуска использовались QProcess).</p><h3>Подсветка синтаксиса</h3><p>«Какая же IDE может быть без подсветки?» — подумал я и решил прикрутить оную. Qt — очень богатый фреймворк, и даже для этой, с виду не такой распространенной задачи, там было решение — QSyntaxHighlighter. Нужно было только отнаследоваться от него и заимплементить функцию highlightBlock, которая будет вызываться автоматически, когда нужно. Функция подсвечивала синтаксис, проходя по списку пар &lt;регулярное выражение QRegExp, необходимый формат текста (цвет, курсив и т.д.)&gt;. Про регулярные выражения узнал опять же из Qt Assistant — очень удобная вещь, с тех пор применял их не в одной задаче.</p><h3>Отладчик</h3><p>По ходу дела я выкладывал первые версии на обозрение однокурсников и получал некоторый фидбек. Одной из самых востребованных и интересных фич был отладчик. И на самом деле, в начале, при написании программ на языке ассемблера, было где наделать ошибок. К тому же для более полного понимания интересно было посмотреть результаты работы отдельных команд (как меняются регистры, как выставляются флаги). Отладчик очень бы помог в этих случаях.</p><p>Решено было использовать стандартный консольный GDB, опять же запуская его через QProcess, на вход подавать нужные команды, соответствующие действиям пользователя в интерфейсе, и разбирая теми же регулярками его вывод.</p><p>Там были свои заморочки, связанные с дебагом именно кода, который получается из программы на языке ассемблера. Это происходило из-за того, что ассемблер NASM не добавлял полной отладочной информации в исполняемый файл (только информацию по функциям и переменным). Приходилось разбирать его листинги, чтобы, например, понять в каком месте в тексте программы мы сейчас находимся (GDB говорил только место в памяти).</p><p>Так или иначе, отладчик был реализован — можно было ходить по программе, ставить брейкпоинты, через некоторое время добавил показ регистров и памяти.</p><h3>Ещё фичи</h3><p>Перевел программу на русский — в приложениях на Qt хороший тон не использовать в коде отличный от английского язык. С помощью Qt это делается очень просто: все строки, которые нужно переводить, заключаются в функцию tr (например, tr(“string to translate”)). Затем Qt Linguist парсит все такие упоминания строк и позволяет перевести их и сохранить в файл с переводом. Этот файл загружается в программе при выборе другого языка.</p><p>В редактор добавил возможность делать правильные отступы табом, комментировать участок кода и другие необходимые мелочи. Добавил вкладки (QTabWidget), настройки цветовой цветов, опций сборки. Все достаточно просто, с точки зрения реализации здесь ничего особенного отметить не смогу.</p><p>В программу была включена библиотека макросов ввода/вывода io.inc для NASM (она была взята из курса «Архитектура и язык ассемблера» и немного изменена для правильной работы с отладчиком, а также была написана ее x64 версия). Она очень удобна для новичков: когда не знаешь соглашения о вызовах и не можешь вызвать printf, очень удобно вызвать макрос из этой библиотеки. Описание макросов библиотеки находится на сайте программы.</p><p>Летом 2014 добавил поддержку x64 и ассемблеров MASM, FASM, GAS (все по аналогии с NASM). Для поддержки нескольких ассемблеров выделил интерфейс Assembler — добавлять новые ассемблеры стало проще.</p><h2>Распространение</h2><p>Проект где-то в середине своего пути был залит на GitHub. На GitHub Pages были сделаны русская и английская версии сайта.</p><p>Размещал сообщения о программе на русскоязычных и иностранных форумах, связанных с программированием на языке ассемблера.</p><p>Летом 2014 написал статью о программе на хабр. Сейчас мне написали из «Типичного программиста» и я сделал эту статью для вас.</p><p>Программа используется в моём университете в рамках курса «Архитектура ЭВМ и язык ассемблера». Также, судя по письмам, SASM используется и в других университетах и колледжах в России и за рубежом. Сайт программы посещает в среднем 100 человек в день.</p><h2>Заключение</h2><p>Опять же замечу, что проект этот OpenSource. Следовательно, любой желающий может присоединиться к разработке и сделать pull request на GitHub. Ну и конечно, можете сообщать о пожеланиях и ошибках в GitHub Issues или на мою почту <a>Dman1095@gmail.com</a>.</p>]]></content:encoded>
    </item>
  </channel>
</rss>