128 байт хватит на всех?

Нет.

Прошлые части: 1 и 2

Уже и 160 к концу подходят

У меня есть традиция. Каждое 31ое декабря я пишу код. Давайте посмотрим, что я успел сделать пока все строгали салаты и провожали 2017ый.

Hello world v2

Сделал чуть-чуть более приличный вариант базовой программки. Дело в том, что большая часть примеров hello world на асме используют прерывание 21h, которое я и попытался реализовать.

Кладем в регистр смещение и дергаем прерывание. Все.

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

std::byte

Мигрировал с char* на std::byte*. По сути своей, это ровно то же самое, только не является символом и автоматически не кастится ни во что. Не скажу, что удобнее, но точно правильнее. Стандарт c++17, даже в Visual Studio 2017 приходится отдельно включать. И fmtlib по дефолту их не умеет. В общем, как обычно, хочешь как лучше и собираешь все возможные грабли.

PUSH & POP

Реализовал стек. Вообще, все тривиально, просто выделил регистр под адрес, одной инструкцией пишу туда, сдвигаю на 4 байта. Другой читаю, сдвигаю обратно. Ессно, если уважаешь себя, надо потестить классику: переполнение стека!

Забиваем нопами, адрес перехода перетирается, мы улетаем за границу памяти. Вуаля, вечный цикл прерван. Прямо настоящие хакеры!

Другие изменения

Добавил регистр EIP для хранения адреса выполнения. Сделал отладочный вывод по-симпатичнее. А главное добавил для большинства инструкций варианты для приема адресов или констант в качестве параметров. Очень трудоемко, но теперь возможностей гораздо больше, да и код писать, хотя это все еще байт-код, стало проще.

Сейчас тестовый код выглядит как-то так.

Конечно, не хватает еще всякого сахарка, но наверное нет особого смысла копать в эту сторону.

TODO

У меня все еще нет никакой обработки ошибок, а она нужна. В том числе и для реализации защищенных адресов.

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

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

Вообще говоря, выглядит оно конечно все довольно круто, но после написания основ, появляется много рутины. Вы, наверное, в курсе, что я долго над одним проектом не работаю, надо как-то удерживать мотивацию. Не знаю, мысли есть и о низкоуровневых вещах, то есть продолжать в асм, и о том, чтобы начать писать отладчик, а может и игрообразную оболочку по примеру tis-100.

Продолжение