1 / 1 / 0
Регистрация: 10.04.2013
Сообщений: 17
|
|
1 | |
Интерпретатор/компилятор ассемблер-подобного языка13.04.2013, 19:48. Показов 4389. Ответов 5
Метки нет Все метки)
(
Привет!
Чую, что изобрёл велисипед, даже скорее велопарк, но всё же, поделюсь: Некоторое время назад начал изучать кресты, в целом не плохо продвигаюсь. Недавно решил доделать программу, которая являлась заданием к книги Дейтелов - про "симплетрон". На этой основе сделал сначала компилятор(если так можно сказать) в байт-код. Далее транслятор этого кода и к нему дебаггер а-ля 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 Интерпретатор и дебаггер с некоторыми примерами прикреплены ниже.
0
|
|
13.04.2013, 19:48 | |
Ответы с готовыми решениями:
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
|
1 / 1 / 0
Регистрация: 10.04.2013
Сообщений: 17
|
|
13.04.2013, 21:26 [ТС] | 4 |
на github'e, внизу оп-поста есть ссылка.
Мне иногда хотелось кинуть), но дело есть дело, и еще нужно годные проекты в портфолио собирать ![]() Повторюсь, что принимаю любые советы по коду или фичам. Кстати, есть извращенное ![]() Может кто знает (и может кратко рассказать) как это устроено в действительности? (ссылки на ядро никсов не предлагать, я не разберусь ![]()
0
|
Kastaneda
|
13.04.2013, 21:33
#5
|
0
|
0 / 0 / 0
Регистрация: 18.12.2016
Сообщений: 1
|
|
18.12.2016, 13:45 | 6 |
Я знаю что пишу не по теме. Пожалуйста, помогите разобраться в одном, эксцентричном вопросе (не нападайте сразу с вилами). Есть такой писатель, Кэндзи Сиратори - он написал книгу смешав 4 языка: язык программирывания С++, английский, японский, латинский. Книга написана от лица кибернетического организма, в форме потока сознания... Он видит мир через среду С++, думает на языке С++. Помогите понять пару фишек с С++ - зачем нужны ‹‹ или ‹‹= – сдвиг влево
›› или ››= – сдвиг вправо зачем нужны :: – разрешение области действия и как вы думаете что имеет ввиду автор (объясните ход мысли этого существа, от лица которого написана книга... наверно не для людей))) ) C++ // – конец блока / – разделитель уровней (мой дом/моя квартира/ моя комната) + – сложение ++ – постфиксное приращение (брить++себя – бриться) ‹‹ или ‹‹= – сдвиг влево ›› или ››= – сдвиг вправо ! – логическое отрицание != – не равно = = – равно = – присвоение (витал=сыворотка – витал стал сывороткой) ‹‹Записываю витал-икону+наши хромосомы из выделений в присос =кровь хромосомы::горизонт жидкостей тела=убить как собаку, разложенную до голого гена =ТВ/спазм// Я разочарован в объёмной инокуляции гидромашины::бесконечный круговорот масс плоти::исчезаю с телом машинной природы ТоК::‹‹высасываю порно нервный газ бойроида// Душа/грамма самосокрушения до квантовой трагедии NDRO// Выход=преступник внутренней-системы-органов›› Определяет++мазо=траффик::от ToKAGE, скапливающихся в городе Городе Трупов// Душа/грамм их разжижают внутренние жидкости тела++себя, что вызывает в цифровом вампире функцию насилия::чудовнще разрастающееся запечатлено в голограмме пса и реверберации// Жестокость замученной памяти/ ‹‹модуль=сердце::рождённое в хаотичных условиях ТоК::клетки мозга, где в дыхании болезненные приступы// Выход::Страх=клетка::осмос::›› Трасса блуждающего нерва::нарко-эмбриона, поданного на вход убийственной игры самого себя как собаку// Тело заразно++в центре среды пытающей техномассы плоти бойроида, истекающей эмоциями киборг-ротора//
0
|
18.12.2016, 13:45 | |
18.12.2016, 13:45 | |
Помогаю со студенческими работами здесь
6
Написать интерпретатор программного языка -помощь Пишем свой интерпретатор языка BASIC Компилятор с С++ на Ассемблер Написать простой компилятор языка C Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |