1 / 1 / 0
Регистрация: 10.04.2013
Сообщений: 17
1

Интерпретатор/компилятор ассемблер-подобного языка

13.04.2013, 19:48. Показов 4516. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет!
Чую, что изобрёл велисипед, даже скорее велопарк, но всё же, поделюсь:

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

В итоге, практически довёл до конца, осталось найти ошибки и дописать логику прерываний.

Как это всё выглядит:

Кратко опишу синтаксис:

Операторы: mov, add, sub, inc, dec, int, loop, jmp, ret, push, push, pop, nop, cmp, jz, jnz, mul, div, mget, mset, call, mod
Из них унарные: add, sub, inc, dec, int, loop, jmp, push, pop, cmp, jz, jnz, call
Бинарные: mov, mul, div, mget, mset, mod
Не принимают значений: ret, nop

Регистры: ax, bx, cx, dx, sp, bp, si, di, cs, ds, ss, es, ip - 16 бит
Регистры ax, bx, cx, dx соответственно имеют свои старшие и младшие половины - ah, al, bh, bl, ch, cl, dh, dl - 8 бит
Из них (в отличии от реального языка) используются:
cs - начало сегмента кода
ds - начало сегмента данных
ss - начало сегмента стека

ip - смещение от cs к текущей команде
sp - указывает на вершину стека

Все остальные не используются(исполнителем), однако все регистры можно свободно менять.

Все бинарные операции кроме одной соответствуют семантике:
[команда] приёмник, источник
Исключение это mset которая записывает значение из левого операнда в адрес памяти по правому операнду
Команда же mget(все остальные команды описывать не буду - надеюсь знаете) берёт из памяти по адресу правого операнда 2 байта, или 1 байт - в зависимости от размера регистра (ah или bx, например)

Все числа могут быть записаны с приставкой h -указывает, что число HEX, иначе считается, что с/с 10.
Например: 50000, FFF0h, CCCCh, 27, 25h

Определение данных рассмотрим на примере:
data1 db 'Hello, world!\n$'
где data1 - название указателя на первый байт данных(только a-zA-Z0-9), db - тип данных, далее следует строка с \n и $ - символ конца строки
Экранирование управляющих символов не реализовано. (а их два - \n и $)
Массивы:
array1 db [100] - массив на 100 байт
array2 dw [100] - массив на 200 байт, dw - data word - слово - 2 байта
или
array1 db 1, 2, 10, 101 - массив на 4 байта
array2 dw 5, FFFFh, 123Fh - массив на 3 слова - 6 байт памяти

Как и в с++ с операторами можно производить математические операции(а-ля арифметика указателей) благодаря команде квадратных скобок:
[array1] - получает адрес первого байта в связке.
Ограничение: операция взятия адреса поддерживается только для данных и может использоватся только как правый операнд в бинарных операциях и только!
Заметьте, что можно и делить и умножать указатели, ведь они - число.

Пример:
array1 db 100, 20h

mov ax, [array1] - взять адрес числа 100(в данном случае)
add ax, 1 или inc ax
mget bl, ax - в bl записывается 20h
mov ch, FFh - это понятно, надеюсь
mset ch, ax - записать по адресу ax значение ah

Если же допустить ошибку, и сделать так:
mov cx, FFAAh
mset cx, [array1]
То запишется уже не 1, а 2 байта(т.к cx - 16 битовый регистр), соответственно получим:
Вырезка из памяти(в hex) до изменения: 64 20
После : FF AA

Бегло скажу о операторах перехода и метках
имя_метки: - метка
loop метка - переход по метке и уменьшение cx на 1
jmp - безусловный переход
jz - перейти, если не установлен zero flag, т.е cmp вернул 0 (= верное равенство)
jnz - перейте если ZF установлен, т.е cmp - не верное равенство
GF - придуманный мною флаг(костыль, ага) установлен, когда правый операнд последнего cmp больше левого.

И, наконец, функции: рассмотрим также на примере

func_label uses ax, bx:
; какие-то действия
ret

можно написать и просто func_label:
uses - говорит, что нужно перед выполнением запихнуть в стек указанные регистры, а перед ret восстановить

Вызывать как :
call func_label
Оператор call перед переходом заносит в стек адрес возврата, так, что нужно быть аккуратным в функции, можно, однако реализовать передачу параметров, если сохранить адрес возврата из стека, и потом его восстановить. Однако проще пользоваться чтением из памяти (нам ведь не критично, память это или регистр - т.к код сам исполняется виртуально, и всё и так находится в памяти)

Фух, вот и всё, что-то явно забыл, но если что - спрашивайте)
Надеюсь, хоть кто-то посмотрит код (часть я подробно прокомментировал), также высказывайте свои советы и предложения - буду рад.
Спасибо за прочтение

P.S в принцепи, легко реализуется длинная арифметика (http://pastebin.com/FHKdSAik)
GIT = https://github.com/cygwin255/CppAsm
Интерпретатор и дебаггер с некоторыми примерами прикреплены ниже.
Вложения
Тип файла: rar Release.rar (91.6 Кб, 56 просмотров)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.04.2013, 19:48
Ответы с готовыми решениями:

Интерпретатор небольшого языка программирования на С++
Здравствуйте, уважаемые форумчане! Я тут где-то год назад прочитал тему Evg и #pragma о создании...

Не удается откомпилировать интерпретатор М-языка
Задача: взять интерпретатор М-языка на сайте...

Пишем свой интерпретатор языка BASIC
***************** Благодаря форуму и Evg в частности интерпретатор развивается, потихоньку...

Написать Интерпретатор Программного Языка(собственного)
Здраствуйте! Кто знает C++ помогите пожалуйста с реализацией данного задания!!! Пожалуйста,...

5
1 / 1 / 0
Регистрация: 10.04.2013
Сообщений: 17
13.04.2013, 20:25  [ТС] 2
Не рассказал, про то, как код преобразуется в байт код..

Все команды байт-кода содержат только 3 байта.
Все бинарные операторы преобразуются по следующему алгоритму:
В коде: mov ax, bx
В obj файле:
push bx
mov ax


Первый байт команда, второй 2 байта - регистр (его код) или числовое значение.
У push 2 версии - первая для регистров, вторая для чисел.

Добавлено через 24 минуты
Поправка в пункте о GF(GreaterFlag) - ... правый операнд последнего cmp меньше левого.

редактировать, почему-то уже не могу.

Добавлено через 6 минут
И еще поправка - add, sub, cmp случайно в унарные записал, в бинарные, конечно.
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,113
Записей в блоге: 2
13.04.2013, 21:13 3
Цитата Сообщение от cygwin Посмотреть сообщение
Надеюсь, хоть кто-то посмотрит код
а где код то?

В целом круто конечно, мне бы лень было все это делать
0
1 / 1 / 0
Регистрация: 10.04.2013
Сообщений: 17
13.04.2013, 21:26  [ТС] 4
Цитата Сообщение от Kastaneda Посмотреть сообщение
а где код то?

В целом круто конечно, мне бы лень было все это делать
на github'e, внизу оп-поста есть ссылка.
Мне иногда хотелось кинуть), но дело есть дело, и еще нужно годные проекты в портфолио собирать

Повторюсь, что принимаю любые советы по коду или фичам.

Кстати, есть извращенное желание допилить к этому всему мультизадачность, только вот думаю как реализовать. Можно поочерёдно проверять список ожидающих выполнения программ(точнее команд) и выполнять каждую по очереди, предварительно сохранив все регистры в стеке и восстановив те, что в другой программе. Но, по моему, это костыли.
Может кто знает (и может кратко рассказать) как это устроено в действительности? (ссылки на ядро никсов не предлагать, я не разберусь)
0
Kastaneda
13.04.2013, 21:33
  #5

Не по теме:

Цитата Сообщение от cygwin Посмотреть сообщение
на github'e, внизу оп-поста есть ссылка.
А точно, что-то не по глазам было.

0
0 / 0 / 0
Регистрация: 18.12.2016
Сообщений: 1
18.12.2016, 13:45 6
Я знаю что пишу не по теме. Пожалуйста, помогите разобраться в одном, эксцентричном вопросе (не нападайте сразу с вилами). Есть такой писатель, Кэндзи Сиратори - он написал книгу смешав 4 языка: язык программирывания С++, английский, японский, латинский. Книга написана от лица кибернетического организма, в форме потока сознания... Он видит мир через среду С++, думает на языке С++. Помогите понять пару фишек с С++ - зачем нужны ‹‹ или ‹‹= – сдвиг влево
›› или ››= – сдвиг вправо
зачем нужны :: – разрешение области действия и как вы думаете что имеет ввиду автор (объясните ход мысли этого существа, от лица которого написана книга... наверно не для людей))) )

C++
// – конец блока
/ – разделитель уровней (мой дом/моя квартира/ моя комната)
+ – сложение
++ – постфиксное приращение (брить++себя – бриться)
‹‹ или ‹‹= – сдвиг влево
›› или ››= – сдвиг вправо
! – логическое отрицание
!= – не равно
= = – равно
= – присвоение (витал=сыворотка – витал стал сывороткой)

‹‹Записываю витал-икону+наши хромосомы из выделений в присос =кровь хромосомы::горизонт жидкостей тела=убить как собаку, разложенную до голого гена =ТВ/спазм// Я разочарован в объёмной инокуляции гидромашины::бесконечный круговорот масс плоти::исчезаю с телом машинной природы ТоК::‹‹высасываю порно нервный газ бойроида// Душа/грамма самосокрушения до квантовой трагедии NDRO// Выход=преступник внутренней-системы-органов›› Определяет++мазо=траффик::от ToKAGE, скапливающихся в городе Городе Трупов// Душа/грамм их разжижают внутренние жидкости тела++себя, что вызывает в цифровом вампире функцию насилия::чудовнще разрастающееся запечатлено в голограмме пса и реверберации// Жестокость замученной памяти/

‹‹модуль=сердце::рождённое в хаотичных условиях ТоК::клетки мозга, где в дыхании болезненные приступы// Выход::Страх=клетка::осмос::›› Трасса блуждающего нерва::нарко-эмбриона, поданного на вход убийственной игры самого себя как собаку// Тело заразно++в центре среды пытающей техномассы плоти бойроида, истекающей эмоциями киборг-ротора//
0
18.12.2016, 13:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.12.2016, 13:45
Помогаю со студенческими работами здесь

Написать интерпретатор программного языка -помощь
Здраствуйте! Ребят, кто хорошо разбирается в C++ помогите пожалуйста с реализацией данного задания...

Пишем свой интерпретатор языка BASIC
Добрый день. Я смотрю, тут на форуме была тема коллективного написания интерпретатора BASIC на...

Компилятор с С++ на Ассемблер
Доброго времени суток. Учусь в институте на заочке, по предмету Теория Языков Программирования дали...

Написать простой компилятор языка C
Помогите с решением данного задания По заданию нужно сделать компилятор который будет решать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru