Форум программистов, компьютерный форум CyberForum.ru

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

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Поиск одинаковых элементов в этой матрице http://www.cyberforum.ru/cpp-beginners/thread836867.html
№1. Дана матрица A(nxn). Написать программу поиска одинаковых элементов в этой матрице.
C++ класс в BorlandC подскажите как в BorlandC 3,1 создать клас выдает ошибку "Declaration syntax error" class bases{ public: virtual void hide(void)=0; virtual void show(void)=0; virtual void move(int dx, int dy)=0; } ругаеться на class bases http://www.cyberforum.ru/cpp-beginners/thread836866.html
C++ Узнать значение пиксела в jpg формате
Доброго времени суток! :) Вопрос такойц: имеется файл формата jpg, как можно узнать чему равняется какой то пиксел?
C++ найти ошибку в программе
Сортировка вещественных чисел из файла методом пузырька #include "stdafx.h" #include <stdio.h> #include <stdlib.h> void BubbleSort(double *arr, int n) { double temp; while(--n)
C++ Пишу паука на microsoft visual C++ 2010 на консоли. Вопрос: как взять ссылки с сайта с глубиной 3 и записать его в файл? http://www.cyberforum.ru/cpp-beginners/thread836857.html
Пишу паука на microsoft visual C++ 2010 на консоли. Вопрос: как взять ссылки с сайта с глубиной 3 и записать его в файл? как запись делается я знаю
C++ Программа обмена значениями двух переменных a и b 3.8 Составить программу обмена значениями двух переменных a и b. Разработать два варианта решения задачи – с исполь-зованием вспомогательной переменной и без нее. Хотя бы блок схемку намекните. . . подробнее

Показать сообщение отдельно
cygwin
1 / 1 / 0
Регистрация: 10.04.2013
Сообщений: 17

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

13.04.2013, 19:48. Просмотров 1450. Ответов 5
Метки (Все метки)

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

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

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

Как это всё выглядит: http://s45.***********/i109/1304/d0/a945bcefc537.png

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

Операторы: 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 Кб, 28 просмотров)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru