Разворачивал в очередной раз Linux-образ на USB-drive (почему-то им оказался Manjaro, но это совсем другая история), и в голову пробрались странные мысли: BIOS увидел флешку, а дальше-то что? Ну да, там MBR, скорее всего GRUB и… А раз в MBR затесался чей-то кастомный код, значит и простой человек из Адыгеи может запрограммировать что-нибудь на «большом» компьютере, но вне операционной системы. А так как делать такие штуки на языках высокого уровня слишком жирно, а ассемблеров мы не знаем, будем шпарить прямо на опкодах для 8086.  Чтобы не докучать домашних грохотом флоповода, тренироваться будем на кошках QEMU. Но, полагаю, желающие смогут всё то же самое нарезать с помощью dd на флешку и запустить на любой x86-совместимой железяке. Это раз. Мы будем крушить MBR, так что если вы где-то её еще используете (зачем?) и захотите нарезать наши результаты на живой накопитель (зачем?) — думайте, прежде чем надавить Enter. Это два. Автор — не настоящий сварщик, и может нести (и обязательно донесёт!) какую-то ересь. (У автора вообще детство Бейсиком сломано.) Набегите в комментарии и всё исправьте! Это три. Для наших низменных целей нам достаточно знать следующее: Для начала, что такое опкоды — для тех, кто не знает. Давным давно, когда компьютеры были большими, а программисты еще не назывались разработчиками, но уже перестали вырезать окошки в перфокартах, они решили писать программы прямо (sic!) на компьютерах. А так как программисты быстро поняли, что делать это в двоичных кодах не очень сподручно (места всё-таки уходит многовато), переводить двоичные числа в шестнадцатеричные может любой дурак, то и листинги писали прямо хексами.  Если видели у бати, а то и деда какой-нибудь «Радио» за 80-е годы или «Моделист-Конструктор» за начало 90-х, то в конце наверняка находили листинги для соответствующих самопайных компьютеров: «РК» или «Специалиста». Там были и «ХО», и клоны Lode Runner, и драйверы для подключения печатной машинки «Консул».   И это только первая страница! Да-да, всё это вбивали ручками, сверяли контрольные суммы, долго матерясь, искали ошибки, и еще больше матерясь — ждали следующего выпуска с errata. Вообще тема непростая, и мне, не имеющему опыта в низкоуровневом программировании, в некоторых местах пришлось думать и яростно откапывать и внимательно читать документацию. Какие моменты нужно взять на заметку: Решил я по началу писать прямо в файлик, который потом подсовывать сначала эмулятору, а потом и dd, чтобы затолкать на железку, но понял, что так для нас, зумеров, будет решительно неудобно — без красивого оформления, комментариев, да билд-системы. Посему я собрался с духом и накатал себе чудо-скрипт, а вот и он… Хотел было написать я, но подумал что умные дядьки из POSIX наверняка всё сделали за меня, и таки да почти да! Осталось придумать синтаксис комментариев и стрипать их: (На самом деле такой выхлоп будет и без sed-а, потому что xxd просто пропускает то, что не смог распарсить как hex-dump. Но мы ведь не хотим неприятностей?) В итоге скриптецкий набросать пришлось, но он оказался не таким большим, каким имел шансы быть. Скрипт в репо А теперь — делай, как я! 512 — именно тот размер, который нас устроит. А как его получить, мы узнаем дальше. Для начала сделаем болванку, которая сформируется в bin-файлик размером в 512B, забитый исключительно ноликами. «Это можно было сделать с помощью dd и /dev/zero, болван!» — скажете вы и окажетесь правы. Но вы только посмотрите, как красиво я расставил эти нолики по колонкам разделил на блоки и расставил поcчитанные на калькуляторе (ну ладно, в ipython) адреса! Болванка в репо Естественно, наши нули ни к чему хорошему не приведут, и, что QEMU, что живая железка обругают нас благим Exception'ом.  Расчешем деревяшку еще немного, отделив блоки, в которых должны будут описываться разделы (но они нам не пригодятся), и сигнатура MBR. Файл целиком Оживим же нашего Буратино, сменив два финальных байта на валидную сигнатуру: Что получилось Запрягаем:  Оно живо, BIOS думает, что эта балалайка его загрузит! Ура, товарищи! Хватит уже мять мышку, пора печатать! Для нашей первой проказы проделки не понадобится практически ничего, даже думать. Посмотрите сами: Файл в репо Всё остальное забито теми же нулями и сигнатуркой (следите за тем, чтобы байтов было 512). Собираем наше ООП, заталкиваем в QEMU и вуаля!  Я уверен, мои безграмотные комментарии всё прояснили, но, на всякий случай, давайте еще разок: Особо инициативные могут поиграться с шрифтами с кодом, отправляемым в AL и добиться вывода: Но все эти одиночные символы, конечно, цветочки. Волчьи ягодки нас ждут впереди. Давайте же принтанём что-нибудь посерьезнее. Тем более сделать это на опкодах — это вам не printf('Hell of word') наклепать. Конечно же, мы можем сделать, как полные удоды: Да, я это закоммитил И, в принципе, мы добились результата:  Давайте немного очеловечим эту штуку: Го смотреть, что получилось в итоге: На деле всё просто: Это всё уже почти похоже на настоящее программирование, но что-то маловато в нашем софте интерактива. Давайте сделаем примитивнейшую печатную машинку: будем с помощью тех же BIOS-функций печатать вводимые символы. А сохранять… Ну сфотографируете экран на телефон. Или потом напишем с вами не менее примитивную файловую систему — но уже в другой статье (не забывайте, статьи я пишу раз в десять лет — и изменять этому правилу я не намерен). Эх, да простят меня низкоуровневые программисты: Новый блоб 1 Давайте разбираться: Ух, поразвлекаемся немножко:  Итого, наша штука может: Но перемещение символов ограничено новой строкой. Что б жизнь emacs-ом не казалась. Маленькие дополнения для тех, кто дочитал до конца. КДПВ родилась из такого выхлопа, который получился из-за неправильного подсчета байтов для джампа:  Я его немного подрихтовал, добавил красивых цветов. В общем, смотрите сами: color-printer.mbr Вот и весь меджик. Определенно, самая полезная глава в моём рассказе. Жена подходит, говорит:
— Хватит работать!
— А я и не работаю.
Заглядывает в экран, видит Sublime Text со всем этим безобразием:
— А-а-а, какой ужас! Это зашифрованная порнуха!
Занавес. В чём-то ведь она права. UPD: Спасибо eisaev, Andrew_Pinkerton, MrSmith33, Anthony1025 и Юле, которая не желает регистрироваться на Хабре, за правку моих ошибок и опечаток. Программист странных вещей