https://tvoygit.ru/stein47/russian-virtual-mashine
(чтобы ссылка на видном месте лежала.)
Ранее по теме:
Первая реализация. Исходники.
Отредактировано Лис (2023-03-11 15:16:08)
Применение искинов - шоссе империализма (Стенгазета русификаторов ИТ) |
Привет, Гость! Войдите или зарегистрируйтесь.
Вы здесь » Применение искинов - шоссе империализма (Стенгазета русификаторов ИТ) » Проект "Виртуальные машины" » Исходные тексты Сказочной Колесницы
https://tvoygit.ru/stein47/russian-virtual-mashine
(чтобы ссылка на видном месте лежала.)
Ранее по теме:
Первая реализация. Исходники.
Отредактировано Лис (2023-03-11 15:16:08)
Обновлены исходники ветки devel-1 - ВМ для языка программирования.
Формат команды и реализованные опкоды.
#если_нет OPCODE_H
#макрос OPCODE_H
//===========================================================
// Файл: opcode.rh
// Версия:
// Дата: 15.06.2022
// Описание:
// Автор:
//===========================================================
/*==================== Структура команды ===================================
* есть возможность адресации 32 регистров общего назначения
--------|-------------------------------------------------------------------|
--------|−31− формат команды (в битах) −0−|
--------|-------------------------------------------------------------------|
КМД_РР | код_рр (6) | резерв (5) | р2 (5) | р1 (5) | рк (5) | код (6) |
--------|-------------------------------------------------------------------|
РЧ | число (16) | р1 (5) | рк (5) | код (6) |
--------|-------------------------------------------------------------------|
П | адрес (26) | код (6) |
--------|-------------------------------------------------------------------|*//*
РР - команды типа регистр-регистр
РЧ - команды типа регистр-число
П - команда перехода (не реализовано)
рк - "конечный" регистр, в который помещается результат операции
р1 - регистр-аргумент №1
р2 - регистр-аргумент №2
*/
перечисление код_рр{
СЛЖ = 1,// 0x01 - рк = р1 + р2 обрабатывается ошибка переполнения
СЛЖб, // 0x02 - рк = р1 + р2 (беззнаковое)
ВЫЧ, // 0x03 - рк = р1 - р2 обрабатывается ошибка переполнения
ВЫЧб, // 0x04 - рк = р1 - р2 (беззнаковое)
УМН, // 0x05 - рк = р1 * р2 обрабатывается ошибка переполнения
УМНб, // 0x06 - рк = р1 * р2 (беззнаковое)
ДЕЛ, // 0x07 - рк = р1 / р2
ДЕЛб, // 0x08 - рк = р1 / р2 (беззнаковое)
ОСТ, // 0x09 - рк = р1 % р2
ОСТб, // 0x0a - рк = р1 % р2 (беззнаковое)
И, // 0x0b - рк = р1 & р2
ИЛИ, // 0x0c - рк = р1 | р2
ИСК, // 0x0d - рк = р1 ^ р2
ИЛИ_НЕ, // 0x0e - рк = ~(р1 | р2)
СДЛ, // 0x0f - рк = р1 << р2
СДП, // 0x10 - рк = р1 >> р2
САП, // 0x11 - рк = р1 >> р2 для отрицательных чисел знаковый бит сохраняется
ЕБ, // 0x12 - рк = (р1 > р2) ? 1 : 0
ЕМ, // 0x13 - рк = (р1 < р2) ? 1 : 0
ЕР, // 0x14 - рк = (р1 == р2) ? 1 : 0
ЕН, // 0x15 - рк = (р1 != р2) ? 1 : 0
Е0, // 0x16 - рк = (р1 == 0) ? 1 : 0
Е, // 0x17 - рк = (р1) ? 1 : 0
// ---------условное выполнение следующей команды---------
ВЕБ, // 0x18 - если (р1 > р2) выполнить след. команду
ВЕМ, // 0x19 - если (р1< р2) выполнить след. команду
ВЕР, // 0x1a - если (р1 == р2) выполнить след. команду
ВЕН // 0x1b - если (р1 != р2) выполнить след. команду
};
перечисление код{
/*00*/ СТОП = 0, // - Остановка работы процессора
/*01*/ КМД_РР =1, // - Это команда регистр-регистр, начинаем поиск по "код_рр"
/*02*/ СЛЖЧ, // - рк = р1 + ч(знаковое)
/*03*/ СЛЖЧб, // - рк = р1(беззнаковое) + ч(знаковое)
/*04*/ ИЧ, // - рк = р1 & ч(знаковое)
/*05*/ ИЛИЧ, // - рк = р1 | ч(знаковое)
/*06*/ ИСКЧ, // - рк = р1 ^ ч(знаковое)
/*07*/ ИЛИ_НЕЧ,// - рк = ~(р1 | ч(знаковое))
/*08*/ ПР, // - cк = р1
/*09*/ ПЧ, // - cк += ч(знаковое)
/*10*/ СДЛЧ, // - рк = р1 << ч(знаковое)
/*11*/ СДПЧ, // - рк = р1 >> ч(знаковое)
/*12*/ САПЧ, // - рк = р1 >> ч(знаковое) для отрицательных чисел знаковый бит сохраняется
/*13*/ ЕБЧ, // - рк = (р1(знаковое) > ч(знаковое)) ? 1 : 0
/*14*/ ЕМЧ, // - рк = (р1(знаковое) < ч(знаковое)) ? 1 : 0
/*15*/ ЕРЧ, // - рк = (р1(знаковое) == ч(знаковое)) ? 1 : 0
/*16*/ ЕНЧ, // - рк = (р1(знаковое) != ч(знаковое)) ? 1 : 0
/*17*/ ИНК, // - рк++
/*18*/ ДЕК, // - рк--
// ------ быстрые команды ---------
// не тратим время на извлечение индексов регистров
// увеличение производительности на 10-30%
/*19*/ ИНК0, // 19 - регистры[0]++
/*20*/ ИНК1, // - регистры[1]++
/*21*/ ИНК2, // - регистры[2]++
/*22*/ ИНК3, // - регистры[3]++
/*23*/ ДЕК0, // - регистры[0]--
/*24*/ ДЕК1, // - регистры[1]--
/*25*/ ДЕК2, // - регистры[2]--
/*26*/ ДЕК3, // - регистры[3]--
// ---------условное выполнение следующей команды---------
/*27*/ ВЕБЧ, // - если (р1(знаковое) > ч(знаковое)) выполнить след. команду
/*28*/ ВЕМЧ, // - если (р1(знаковое) < ч(знаковое)) выполнить след. команду
/*29*/ ВЕРЧ, // - если (р1(знаковое) == ч(знаковое)) выполнить след. команду
/*20*/ ВЕНЧ, // 30 - если (р1(знаковое) != ч(знаковое)) выполнить след. команду
// ---------команды работы со стеком---------
/*31*/ ПМСТ, // - поместить в стек 8-байтное значение
/*32*/ ПМСТ4, // - поместить в стек 4-байтное значение
/*33*/ ПМСТ2, // - поместить в стек 2-байтное значение
/*34*/ ПМСТ1, // - поместить в стек 1-байтное значение
/*35*/ ИЗВЛ, // - извлечь из стека 8-байтное значение
/*36*/ ИЗВЛ4, // - извлечь из стека 4-байтное значение
/*37*/ ИЗВЛ2, // - извлечь из стека 2-байтное значение
/*38*/ ИЗВЛ1 // - извлечь из стека 1-байтное значение
};
#к_если //OPCODE_H
Отредактировано Евгений (2023-04-09 19:37:44)
Создаем маленькую тестовую программу в байт-кодах для тестирования ВМ.
Сначала вспомогательные макрос-функции для кодирования
// макрос-функция для кодирования команд типа регистр-число
#макрос закодировать_команду_рр(_код_рр, _индекс_р2, _индекс_р1, _индекс_рк, _код)\
(_код_рр << 26) | (_индекс_р2 << 16) \
| (_индекс_р1 << 11) | (_индекс_рк << 6) \
| (_код)
// макрос-функция для кодирования команд типа регистр-число
#макрос закодировать_команду_рч(_число, _индекс_р1, _индекс_рк, _код)\
((б16)_число << 16) | (_индекс_р1 << 11) \
| (_индекс_рк << 6) | (_код)
// макрос-функция для кодирования "быстрых" команд
#макрос закодировать_команду_б(_код) закодировать_команду_рч(0, 0, 0, _код)
С помощью подготовленных макросов создаем маленькую программку и записываем в файл.
/**************************************************************/
// программа состоящая их девяти тестовых инструкций.
Ткоманда32 программа[13];
// обнуление регистров р0 и р3
программа[0] = закодировать_команду_рр( ИСК, 0, 0, 0, КМД_РР); // р0 =р0 ^ р0
программа[1] = закодировать_команду_рр( ИСК, 3, 3, 3, КМД_РР); // р3 =р3 ^ р3
// загрузка чисел в р0 и р3
программа[2] = закодировать_команду_рч( 1000 , 0, 0, СЛЖЧ); // р0 =р0 + 1000
программа[3] = закодировать_команду_рч( 10000 , 3, 3, СЛЖЧ); // р3 =р3 + 10000
// перемножение р0 и р3, результат в р3
программа[4] = закодировать_команду_рр( УМНб, 3, 0, 3, КМД_РР); // р3 =р0 * р3
// обнуление регистра р4
программа[5] = закодировать_команду_рр( ИСК, 4, 4, 4, КМД_РР); // р4 =р4 ^ р4
// декремент регистра р3
программа[6] = закодировать_команду_б(ДЕК3); // р3 = р3 - 1
// сравнить р3 и рч, если не равно, то выполнить след команду
программа[7] = закодировать_команду_рр( ВЕН, 4, 3, 3, КМД_РР); // если (р3 != р4) то выполнить след команду
// переход вверх на две команды
программа[8] = закодировать_команду_рч(-2, 3, 3, ПЧ); // переход на 2 команды вверх
// окончание работы
программа[9] = закодировать_команду_б(СТОП);
/************************************************************/
/************************************************************/
// Записываем программу в файл
FILE* файл = fopen ("program.byte", "wb");
если (! файл){
// если не получилось
пчф("Не открыть");
}
если ( fwrite ((void*) программа, 13*4 , 1, файл ) !=1) {
пчф("Не записать");
}
fclose(файл );
ШАГ_ОТЛАДКИ;
/****************************************************************/
Отредактировано Евгений (2023-04-06 16:15:05)
Надо свести все ветки в одну, потому что вот ты мне сказал, что надо посмотреть твой .pdf, а там их столько, что глаза разбегаются (и инструкции нет).
Вы здесь » Применение искинов - шоссе империализма (Стенгазета русификаторов ИТ) » Проект "Виртуальные машины" » Исходные тексты Сказочной Колесницы