Категория > Новости > МикроБ. Пишем бейсик на ассемблере и умещаем в 512 байт - «Новости»
МикроБ. Пишем бейсик на ассемблере и умещаем в 512 байт - «Новости»13-05-2020, 16:09. Автор: Bradshaw |
Хочешь попрактиковаться в кодинге на ассемблере? Давай вместе шаг за шагом создадим интерпретатор бейсика и запустим его прямо из загрузочного сектора твоего компьютера. Для этого придется задействовать перекрывающиеся подпрограммы с разветвленной рекурсией, иначе бейсик не уместится в 512 байт. Скорее всего, это будет самая сложная программа в твоей жизни. Когда ты создашь ее своими руками, сможешь без зазрения совести называть себя хакером. INFO С месяц назад я рассказывал, как написать игрушку FloppyBird, которая тоже умещалась в бутсектор. Но по сравнению с тем, что мы с тобой сотворим сейчас, она покажется тебе мелкой шалостью.
Как пользоваться интерпретаторомПо сути, написав бейсик для бутсектора, мы превратим твой ПК в аналог старых домашних компьютеров типа Commodore 64 или ZX Spectrum, которые имели этот язык в ПЗУ и позволяли программировать на нем сразу после загрузки. Техническое задание (что будет уметь наш интерпретатор) я сформулирую в виде инструкции пользователя. Вот она. Интерпретатор работает в двух режимах: интерактивном и обычном. В интерактивном режиме он выполняет команды сразу после ввода. В обычном режиме сначала надо занести исходник программы в память и затем дать команду Если нужно удалить строку РёР· РёСЃС…РѕРґРЅРёРєР°, просто введи РІ командной строке ее номер. Как интерпретатор узнаёт, РІ каком режиме обрабатывать текст РёР· командной строки? Если строка начинается СЃ номера, интерпретатор обрабатывает ее РІ обычном режиме. Если РЅРµ СЃ номера — РІ интерактивном. Максимальный размер программы — 999 строчек. Максимальная длина строки — 19 символов. Обрати внимание, что клавиша Backspace функционирует как надо. Хоть РЅР° экране СЃРёРјРІРѕР» Рё РЅРµ затирается, РІ буфере РІСЃРµ РІ РїРѕСЂСЏРґРєРµ. Р’ распоряжении Сѓ программиста:
Вот языковые конструкции, которые понимает наш интерпретатор:
Пример: Начинаем делать интерпретаторНачинаем с того, что задаем области памяти, которыми будем пользоваться:
Все сегментные регистры нацеливаем на Р?СЃС…РѕРґРЅРёРє программы РЅР° бейсике будем обрабатывать как двумерный символьный массив: 1000 Г— 20. Если введешь строку больше 19 символов, РѕРЅР° заедет РЅР° соседнюю. Р’ текущей реализации интерпретатора этот баг РЅРµ отслеживается. Просто РїРѕРјРЅРё, что больше 19 символов РІ строчку вписывать нельзя. Запускаем главный рабочий циклЗдесь сначала восстанавливаем указатель стека (регистр Затем сбрасываем указатель running (текущая строка программы). Потом вызываем подпрограмму Дальше смотрим, начинается строка с номера или нет. Если с номера, нам надо записать ее в буфер, который отведен под исходник. Для этого сначала вычисляем адрес, куда записывать строку. За это у нас отвечает подпрограмма Если РІ начале строки нет номера, сразу выполняем ее: Обрабатываем строки программыСтроки программы обрабатываем следующим образом. Берем первое слово из строки и последовательно сравниваем его с каждой записью из таблицы Обрати внимание, какую эвристику СЏ здесь использую, чтобы сэкономить байты РЅР° обработку условного оператора. Перед точкой РІС…РѕРґР° Зачем? Чтобы РЅРµ надо было писать отдельный обработчик для конструкций РІСЂРѕРґРµ РЎ Но если строка не пустая, присматриваемся к ней внимательно. Сначала перебираем по порядку таблицу Если совпадение обнаружилось, то регистр Если всю таблицу перебрали, но совпадения так и не нашли, значит, текущая строка программы — это не команда, не оператор и не функция. Раз так, может быть, это название переменной? Прыгаем на Дальше проматываем регистр Теперь Если РјС‹ прошли РІСЃСЋ таблицу, РЅРѕ так Рё РЅРµ нашли совпадения, значит, текущая строка — РЅРµ команда, РЅРµ оператор Рё РЅРµ функция. Р’ таком случае это, скорее всего, конструкция присваивания РІСЂРѕРґРµ Теперь нам надо вычислить выражение После того как адрес найден, проверяем, есть ли после имени переменной оператор присваивания. Если РґР°, нам надо его выполнить. РќРѕ РІ целях СЌРєРѕРЅРѕРјРёРё байтов РјС‹ сделаем это РЅРµ здесь. Чуть ниже нам СЃ тобой так Рё так придется реализовывать присваивание внутри функции Если знака присваивания нет, печатаем сообщение РѕР± ошибке Рё прекращаем выполнение программы, то есть прыгаем РЅР° Перейти обратно к новости |