МикроБ. Пишем бейсик на ассемблере и умещаем в 512 байт - «Новости» » Самоучитель CSS
Меню
Наши новости
Учебник CSS

Невозможно отучить людей изучать самые ненужные предметы.

Введение в CSS
Преимущества стилей
Добавления стилей
Типы носителей
Базовый синтаксис
Значения стилевых свойств
Селекторы тегов
Классы
CSS3

Надо знать обо всем понемножку, но все о немногом.

Идентификаторы
Контекстные селекторы
Соседние селекторы
Дочерние селекторы
Селекторы атрибутов
Универсальный селектор
Псевдоклассы
Псевдоэлементы

Кто умеет, тот делает. Кто не умеет, тот учит. Кто не умеет учить - становится деканом. (Т. Мартин)

Группирование
Наследование
Каскадирование
Валидация
Идентификаторы и классы
Написание эффективного кода

Самоучитель CSS

Вёрстка
Изображения
Текст
Цвет
Линии и рамки
Углы
Списки
Ссылки
Дизайны сайтов
Формы
Таблицы
CSS3
HTML5

Новости

Блог для вебмастеров
Новости мира Интернет
Сайтостроение
Ремонт и советы
Все новости

Справочник CSS

Справочник от А до Я
HTML, CSS, JavaScript

Афоризмы

Афоризмы о учёбе
Статьи об афоризмах
Все Афоризмы

Видео Уроки


Видео уроки
Наш опрос



Наши новости

       
13-05-2020, 16:09
МикроБ. Пишем бейсик на ассемблере и умещаем в 512 байт - «Новости»
Рейтинг:
Категория: Новости

Хочешь попрактиковаться в кодинге на ассемблере? Давай вместе шаг за шагом создадим интерпретатор бейсика и запустим его прямо из загрузочного сектора твоего компьютера. Для этого придется задействовать перекрывающиеся подпрограммы с разветвленной рекурсией, иначе бейсик не уместится в 512 байт. Скорее всего, это будет самая сложная программа в твоей жизни. Когда ты создашь ее своими руками, сможешь без зазрения совести называть себя хакером.
МикроБ. Пишем бейсик на ассемблере и умещаем в 512 байт - «Новости»
INFO

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



Как пользоваться интерпретатором


По сути, написав бейсик для бутсектора, мы превратим твой ПК в аналог старых домашних компьютеров типа Commodore 64 или ZX Spectrum, которые имели этот язык в ПЗУ и позволяли программировать на нем сразу после загрузки.


Техническое задание (что будет уметь наш интерпретатор) я сформулирую в виде инструкции пользователя. Вот она.


Интерпретатор работает в двух режимах: интерактивном и обычном. В интерактивном режиме он выполняет команды сразу после ввода.




В обычном режиме сначала надо занести исходник программы в память и затем дать команду run.


Если нужно удалить строку из исходника, просто введи в командной строке ее номер.


Как интерпретатор узнаёт, в каком режиме обрабатывать текст из командной строки? Если строка начинается с номера, интерпретатор обрабатывает ее в обычном режиме. Если не с номера — в интерактивном.


Максимальный размер программы — 999 строчек. Максимальная длина строки — 19 символов. Обрати внимание, что клавиша Backspace функционирует как надо. Хоть на экране символ и не затирается, в буфере все в порядке.


В распоряжении у программиста:


  • три команды: run (стирает программу), list (выводит РёСЃС…РѕРґРЅРёРє РЅР° экран), new (запускает программу);

  • 26 переменных (от a до z): двухбайтовые целые числа без знака;

  • выражения, которые могут включать в себя: числа, четыре арифметические операции, скобки, переменные;

  • три оператора: if, goto, =;

  • РґРІРµ функции: print, input.

Вот языковые конструкции, которые понимает наш интерпретатор:


  • var=expr присваивает значение expr переменной var (от a до z);

  • print expr выводит значение expr и переводит курсор на следующую строку;

  • print expr; выводит значение expr и оставляет курсор на текущей строке;

  • print "][ello" печатает строку Рё переводит РєСѓСЂСЃРѕСЂ РЅР° следующую строку;

  • print "][ello"; печатает строку и оставляет курсор на текущей строке;

  • input var считывает значение СЃ клавиатуры, помещает его РІ переменную var (a..z);

  • goto expr переходит РЅР° указанную строку программы;

  • if expr1 goto expr2 — если expr1 РЅРµ 0, прыгнуть РЅР° строку expr2, иначе на следующую после if.

Пример: if c-5 goto 2 (если c-5 не 0, прыгаем на строку 2).


Начинаем делать интерпретатор


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


  • буфер для текста из командной строки;

  • буфер для хранения исходника программы;

  • массив для хранения переменных (от a до z);

  • указатель на текущую строку программы.



Все сегментные регистры нацеливаем на CS. Затем сбрасываем «флаг направления», чтобы строки обрабатывались слева направо, Р° РЅРµ наоборот (РєРѕРіРґР° будем обращаться Рє инструкциям РІСЂРѕРґРµ stosb). Буфер, который предназначен для исходника программы, заполняем символом 0x0D (СЃРёРјРІРѕР» возврата каретки, более известный как клавиша Enter).


Р?СЃС…РѕРґРЅРёРє программы РЅР° бейсике будем обрабатывать как двумерный символьный массив: 1000 Г— 20.


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


 

Запускаем главный рабочий цикл


Здесь сначала восстанавливаем указатель стека (регистр SP). На тот случай, если программа на бейсике обрушилась из-за ошибки.


Затем сбрасываем указатель running (текущая строка программы). Потом вызываем подпрограмму input_line, которая ждет, РїРѕРєР° программист что-РЅРёР±СѓРґСЊ напечатает. Подпрограмма сохраняет полученную строку РІ регистр SI.


Дальше смотрим, начинается строка с номера или нет. Если с номера, нам надо записать ее в буфер, который отведен под исходник. Для этого сначала вычисляем адрес, куда записывать строку. За это у нас отвечает подпрограмма find_address (результат кладет РІ регистр DI). Определив нужный адрес, копируем туда строку: rep movsb.


Если в начале строки нет номера, сразу выполняем ее: execute_statement.



Обрабатываем строки программы


Строки программы обрабатываем следующим образом. Берем первое слово из строки и последовательно сравниваем его с каждой записью из таблицы @@statements (СЃРј. РІРЅРёР·Сѓ статьи последний РєСѓСЃРѕРє РєРѕРґР°). Р’ этой таблице общим СЃРїРёСЃРєРѕРј перечислены команды, операторы Рё функции, которые понимает наш интерпретатор.


Обрати внимание, какую эвристику СЏ здесь использую, чтобы сэкономить байты РЅР° обработку условного оператора. Перед точкой РІС…РѕРґР° execute_statment я поставил дополнительный вход в ту же самую подпрограмму: @@if_handler.


Зачем? Чтобы РЅРµ надо было писать отдельный обработчик для конструкций РІСЂРѕРґРµ if a-2 goto 10. Если результат выражения (в данном случае a-2) равняется нулю, РјС‹ РЅРµ заходим РІ if, то есть игнорируем остаток строки (в нашем случае goto 10).


РЎ if разобрались. Дальше обрабатываем остальные команды, операторы и функции. Начинаем с того, что пропускаем лишние пробелы, которые программист добавил для своего удобства. Если в строке нет ничего, кроме пробелов, просто игнорируем ее.




Но если строка не пустая, присматриваемся к ней внимательно. Сначала перебираем по порядку таблицу @@statements Рё сверяем СЃРІРѕСЋ строку СЃ каждой записью оттуда. Каким образом сверяем? Считываем размер строки (РІ случае run это 3) Рё затем сравниваем, используя repe / cmpsb.


Если совпадение обнаружилось, то регистр DI теперь указывает РЅР° соответствующий адрес обработчика. Поэтому РјС‹ без лишних телодвижений прыгаем туда: jmp [di]. Чтобы лучше понять, в чем тут прикол, загляни в конец статьи, посмотри, как устроена таблица @@statements. Подсказка: метки, которые начинаются СЃ @@, — это как раз и есть адреса обработчиков.


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


Дальше проматываем регистр DI к следующей записи таблицы. Каким образом? Прибавляем CX (длина имени текущей команды, оператора или функции плюс еще РґРІР° байта (адрес обработчика). Потом восстанавливаем значение регистра SI (rep cmpsb перемотала его вперед), чтобы РѕРЅ опять указывал РЅР° начало строки, РїРѕ которой РјС‹ выполняем РїРѕРёСЃРє РІ таблице операторов.


Теперь DI указывает на следующую запись из таблицы. Если эта запись ненулевая, прыгаем на @@next_entry, чтобы сравнить строку программы, вернее ее начало, СЃ этой записью.


Если РјС‹ прошли РІСЃСЋ таблицу, РЅРѕ так Рё РЅРµ нашли совпадения, значит, текущая строка — РЅРµ команда, РЅРµ оператор Рё РЅРµ функция. Р’ таком случае это, скорее всего, конструкция присваивания РІСЂРѕРґРµ var=expr. По идее, других вариантов больше нет. Если, конечно, в исходник не закралась синтаксическая ошибка.


Теперь нам надо вычислить выражение expr Рё поместить результат РїРѕ адресу, СЃ которым связана переменная var. Подпрограмма get_variable вычисляет нужный нам адрес Рё кладет его РЅР° стек.


После того как адрес найден, проверяем, есть ли после имени переменной оператор присваивания. Если да, нам надо его выполнить. Но в целях экономии байтов мы сделаем это не здесь.


Чуть ниже нам СЃ тобой так Рё так придется реализовывать присваивание внутри функции input. Вот на тот кусок кода мы и прыгнем: @@assign. Целиком нам тут функция input ни к чему. Понадобится только ее финальная часть, вот ее и берем. Обратно в execute_statment возвращаться РЅРµ будем. Нужный ret выполнит сама функция input.


Если знака присваивания нет, печатаем сообщение РѕР± ошибке Рё прекращаем выполнение программы, то есть прыгаем РЅР° @@main_loop. Там интерпретатор восстановит указатель стека и сможет работать дальше, несмотря на то что наткнулся на синтаксическую ошибку.



Хочешь попрактиковаться в кодинге на ассемблере? Давай вместе шаг за шагом создадим интерпретатор бейсика и запустим его прямо из загрузочного сектора твоего компьютера. Для этого придется задействовать перекрывающиеся подпрограммы с разветвленной рекурсией, иначе бейсик не уместится в 512 байт. Скорее всего, это будет самая сложная программа в твоей жизни. Когда ты создашь ее своими руками, сможешь без зазрения совести называть себя хакером. INFO С месяц назад я рассказывал, как написать игрушку FloppyBird, которая тоже умещалась в бутсектор. Но по сравнению с тем, что мы с тобой сотворим сейчас, она покажется тебе мелкой шалостью. Как пользоваться интерпретатором По сути, написав бейсик для бутсектора, мы превратим твой ПК в аналог старых домашних компьютеров типа Commodore 64 или ZX Spectrum, которые имели этот язык в ПЗУ и позволяли программировать на нем сразу после загрузки. Техническое задание (что будет уметь наш интерпретатор) я сформулирую в виде инструкции пользователя. Вот она. Интерпретатор работает в двух режимах: интерактивном и обычном. В интерактивном режиме он выполняет команды сразу после ввода. В обычном режиме сначала надо занести исходник программы в память и затем дать команду run. Если нужно удалить строку РёР· РёСЃС…РѕРґРЅРёРєР°, просто введи РІ командной строке ее номер. Как интерпретатор узнаёт, РІ каком режиме обрабатывать текст РёР· командной строки? Если строка начинается СЃ номера, интерпретатор обрабатывает ее РІ обычном режиме. Если РЅРµ СЃ номера — РІ интерактивном. Максимальный размер программы — 999 строчек. Максимальная длина строки — 19 символов. Обрати внимание, что клавиша Backspace функционирует как надо. Хоть РЅР° экране СЃРёРјРІРѕР» Рё РЅРµ затирается, РІ буфере РІСЃРµ РІ РїРѕСЂСЏРґРєРµ. Р’ распоряжении Сѓ программиста: три команды: run (стирает программу), list (выводит РёСЃС…РѕРґРЅРёРє РЅР° экран), new (запускает программу); 26 переменных (от a до z): двухбайтовые целые числа без знака; выражения, которые могут включать в себя: числа, четыре арифметические операции, скобки, переменные; три оператора: if, goto, =; РґРІРµ функции: print, input. Р’РѕС‚ языковые конструкции, которые понимает наш интерпретатор: var=expr присваивает значение expr переменной var (от a до z); print expr выводит значение expr и переводит курсор на следующую строку; print expr; выводит значение expr и оставляет курсор на текущей строке; print "]_

Теги: CSS

Просмотров: 476
Комментариев: 0:   13-05-2020, 16:09
Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

 
Еще новости по теме:



Другие новости по теме:
Комментарии для сайта Cackle