Важная информация

User Tag List

Страница 5 из 6 ПерваяПервая 123456 ПоследняяПоследняя
Показано с 41 по 50 из 58

Тема: Нужна виртуальная машина на ZX

  1. #41
    Banned
    Регистрация
    01.12.2010
    Адрес
    г. Санкт-Петербург
    Сообщений
    1,657
    Записей в дневнике
    21
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Я написал свой интерпретатор. Стековый, но на этапе оптимизации стековые команды объединяются и рождаются безстековые операции. Дать его не могу, но могу помочь советами.

    Там получился такой набор команд:

    opCallFunction - вызвать стандартную функцию
    opCallMethod - вызвать метод класса
    opCall - вызов собственный метод (подпрограмму)
    opPushSelf - поместить в стек this (указатель на свой объект)
    opJmp - перейти на строку
    opLongJmp - перейти на строку и освободить стек
    opRet - завершить выполнение

    Далее обработка исключений.

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

    И опкоды, которые используются только в блоках FINALLY..END или EXCEPT..END (catch...end):

    opTryFinallyEnd - если на верхушке стека лежит не NULL, то исключение. Иначе освободить стек.
    opThrow - сгенерировать исключение по объекту лежащему в стеке.
    opGetExceptionText - поместить в стек текст исключения из объекта лежащего в стеке.

    Далее идут команды для работы с типами данных VARIANT, OBJECT, INTEGER, FLOAT, BOOLEAN, STRING, CURRENCY ...

    Например набор команд для Integer:

    opPush_i - Поместить в стек непосредственное значение
    opPop_i - Освободить стек от Integer (увеличить указатель стека на sizeof(Integer))
    opPushVar_i - Из переменных в стек
    opPopVar_i - Сохранить из стека в переменные
    opPushObj_i - Из объекта в стек
    opPopObj_i - Из стека в объект
    opDup_i - Дублировать значение в стеке

    opAdd_i,opSub_i,opMul_i,opDivInt_i,opDiv_i,opMod_i ,
    opAnd_i,opOr_i,opXor_i,opCmpE_i,opCmpNE_i,opCmpL_i ,
    opCmpG_i,opCmpLE_i,opCmpGE_i,opCmpNEX_i,opNeg_i,
    opShl_i, opShr_i - эти команды производят операцию с парой чисел на верхушке стека так, что остается одно число.

    Да, а команда условного перехода всего одна. Она в наборе команд Boolean:

    opJt_b - Перейти, если TRUE.

    Но оптимизатор пораждает массу команд перехода. Например, opNeg_b + opJt_b заменяет на opJf_b

    В результате оптимизации может рождится команда типа:
    opPushVar_i_opPush_i_opCmpE_opJf_i(A, B, C)
    которая вообще не работает со стеком. Она выполняет действие
    if(variables[A] == B) ip += C;

    Или вот пример оптимизации получения элемента массива:
    opPush_i 0
    opPushObj_o номер
    opPushVar_i номер
    opCallMethod arrayOfInteger::getItem
    opPop_i
    opPop_o
    Заменяется на единственный опкод:
    opArrayOfIntegerGet_o_v(A,B)
    Который выполняет действие:
    ArrayOfInteger* a = objectVariables+A; if(B>=a->count) throw_bound(); *st++ = a->items[B];

    Эти все оптимизации ускоряют работу, но размер исходника интерпретатора занимает несколько сотен килобайт.
    Последний раз редактировалось vinxru; 12.01.2012 в 17:49.

  2. #42
    Master
    Регистрация
    17.05.2005
    Адрес
    г. Абакан
    Сообщений
    694
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Griv, это кто же это кинулся в кодерство? Я написал "от фонаря" байт код, типа с пояснениями, в стековой реализации, которая на мой, может быть не хужее "хипной". А ТЗ мы уже похерили, только вот медведь не делится на ноль, хоть тресни меня битой в лоб
    Уже несколько раз перечитал первый пост AlCo, возникло подозрение, что первоначальная мысль была отнюдь не за байт-код, а именно некоторое подобие муляции кода Z80 с возможностью дополнения новыми командами а-ля префикс типа неиспользуемого rst x.
    AlCo, выходи уже из раздумий, а то я пошел за варенным кофе!

  3. #43
    Guru
    Регистрация
    03.01.2006
    Адрес
    Рязань
    Сообщений
    2,935
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    1
    Поблагодарили
    1 сообщение
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от NovaStorm Посмотреть сообщение
    Код плотнее Z80 сделать будет трудно, над этим думали создатели и 8080, и Z80.
    Даже код калькулятора бейсика плотнее. См. питона в Info Guide #10.

    У меня пока идей нет. Байт-код явы мне весьма понравился.

  4. #44
    Veteran Аватар для Oleg N. Cher
    Регистрация
    24.08.2007
    Адрес
    Днепропетровская обл.
    Сообщений
    1,622
    Спасибо Благодарностей отдано 
    2,204
    Спасибо Благодарностей получено 
    143
    Поблагодарили
    109 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от alone Посмотреть сообщение
    Трезвой форт-машины для Z80 не знаю. Покажите процедуру NEXT.
    Есть одна идея, как можно реализовать наиболее быстрый вариант виртуальной машины на Z80 — может и не по всем пунктам, обозначенным топикстартером, но вариант интересный. Судите сами.

    Это аналог Форт-машины с прямым шитым кодом. Подпрограммный шитый код мы не рассматриваем, потому что это фактически подмножество машинного кода, просто организованный массив подпрограмм со своей логикой.

    1. Код плотнее, чем на Z80.

    Отчасти, да. Интересные вещи писали авторы отечественных Форт-систем о компактности фортовского шитого кода, который превосходил реализации с машинным кодом.

    2. Перемещаемость (помогло бы для ОС с одним окном памяти, где код лежит внизу).

    Нет, потому что код шитый. Или разве что да, но будет требоваться простая настройка адресов, что не должно вызвать проблем.

    3. Реентерабельность (опять-таки для ОС).

    Вероятно, это можно реализовать.

    4. Возможность использования ассемблерных вставок с ограничениями.

    Безусловно.

    Прямой шитый код Форт-машины — это последовательность адресов вызываемых подпрограмм на Форте или в машинном коде. Для Z80 может выглядеть примерно так:

    Код:
    DW LITERAL_BYTE ; Заносим на стек
    DB 5 ; число 5
    DW DUP ; Дублируем значение на стеке
    DW MULT ; Умножаем само на себя (возводим в квадрат)
    DW EMIT ; Печать числа
    Вероятно, большой проблемой будет слово NEXT, от которого сильно зависит скорость работы всей машины. (NEXT передаёт управление следующему за текущим словом. Вероятно, имеет смысл модифицировать шитый код для большей производительности слова NEXT, если это вообще возможно. Моё предложение имеет один минус, который многим покажется критичным. Тем не менее, всё-таки посмотрите, что предлагается.

    Код:
    DI
    LD SP, ExecThread
    RET
    
    DW EMIT ; Адреса слов потока исполнения, но в обратном порядке
    DW MULT
    DW DUP
    DB 5
    DW LITERAL_BYTE
    ExecThread: ; Сюда устанавливается верхушка стека
    В такой реализации словом NEXT в шитом коде будет адрес, указывающий на RET (и обычный RET в машинных подпрограммах). Не все проблемы решены. Остаются трудности с вложенными вызовами шитого кода из шитого кода (или из машинной подпрограммы) — нужно куда-то сохранить адреса возврата. Значит нужен стек, притом не SP, ибо он активно занят другими делами. Если вложенность гарантированно будет одинарная (ну, такой гипотетический случай), должно хватить одного регистра под это. Например, IY.

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

    Плюсы решения: при запрещённых прерываниях не нужно на них отвлекаться процу — код будет работать быстрее. Второй плюс — такая машина может быть регистровой, а не стековой, как Форт. И параметры будут передаваться в регистрах.

    Практическое применение этой идее наверно найти трудно, но вдруг у кого-то появится мысль как её усовершенствовать.

    P.S. На законченность концепции не претендую — так, сырая идея.

  5. #45
    Veteran
    Регистрация
    06.05.2006
    Адрес
    Ливны, Орловская обл
    Сообщений
    1,169
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    А что бы и не JP (HL)? Да и это всё равно мелочи реализации.

  6. #46
    Guru Аватар для jerri
    Регистрация
    01.03.2005
    Адрес
    Samara
    Сообщений
    4,752
    Спасибо Благодарностей отдано 
    271
    Спасибо Благодарностей получено 
    286
    Поблагодарили
    214 сообщений
    Mentioned
    12 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Oleg N. Cher, Идея неплохая
    рекомендую также посмотреть игру IronLord от UbiSoft

    Разумеется изнутри
    есть вероятность что либо Форт либо какой то свой язык
    С уважением,
    Jerri / Red Triangle.

  7. #46
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  8. #47
    Veteran
    Регистрация
    06.05.2006
    Адрес
    Ливны, Орловская обл
    Сообщений
    1,169
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Код:
    DI
    LD SP, ExecThread
    RET
    Вот подумалось тут ещё, а адреса-то должны быть виртуальными...
    Последний раз редактировалось NovaStorm; 13.08.2012 в 12:02.

  9. #48
    Veteran
    Регистрация
    08.05.2007
    Адрес
    Dnepropetrovsk
    Сообщений
    1,058
    Спасибо Благодарностей отдано 
    220
    Спасибо Благодарностей получено 
    47
    Поблагодарили
    31 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Олег, данная концепция именно в том виде, как вы описали, используется в ксорке-защите от Max Iwamoto. Можно посмотреть во многих его Cracktro к играм. На стеке лежала куча адресов, каждый из которых указывал на коротенькую подпрограмму, заканчивавшуюся, как правило, командой RET.

    Максом Ивамото, конечно, преследовалась цель не уплотнить код, а запутать его. Но эта задача не была им решена. Стоит только разобраться с основной идеей, что на стеке расположена фактически программа из инструкций, семантика которых задается лежащими на стеке адресами подпрограмм - как все становится понятно, а изучающий эту защиту получает чувство глубокого удовлетворения от знакомства с красивой концепцией и легкостью, с которой он ее взломал. Каждой "инструкции" присваивается мнемоника, потом адреса подпрограмм заменяются на эти мнемоники - и вуаля, программа как на ладони. Там и циклы были, и условные переходы и, конечно же, регистр R.

  10. #49
    Banned
    Регистрация
    25.01.2005
    Адрес
    Miass, Chelyabinsk region
    Сообщений
    4,094
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    2
    Поблагодарили
    2 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    а сейчас это называется Return Oriented Programming и широко используется во взломах программ.

  11. #50
    Veteran
    Регистрация
    29.12.2010
    Адрес
    Москва
    Сообщений
    1,858
    Спасибо Благодарностей отдано 
    131
    Спасибо Благодарностей получено 
    104
    Поблагодарили
    62 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Oleg N. Cher Посмотреть сообщение
    Код:
    DI
    LD SP, ExecThread
    RET

    DW EMIT ; Адреса слов потока исполнения, но в обратном порядке
    DW MULT
    DW DUP
    DB 5
    DW LITERAL_BYTE
    ExecThread: ; Сюда устанавливается верхушка стека

    Теперь о самом главном минусе. Это конечно запрещённые прерывания. Не вижу способа их разрешить. Полумерой предлагаю лёгкую подпрограмму, которую можно будет вручную вызывать время от времени из своих подпрограмм.
    А почему прерывания должны быть запрещены?
    *(Извините, если что, башка от жары перестала варить)

Страница 5 из 6 ПерваяПервая 123456 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. ZXMAK2 - Виртуальная машина ZX Spectrum
    от ZXMAK в разделе Эмуляторы
    Ответов: 1974
    Последнее: 07.03.2024, 23:45
  2. Машина Тьюринга для Z80
    от ZXMAK в разделе Эмуляторы
    Ответов: 4
    Последнее: 15.08.2011, 03:26
  3. Продвинутая Мелко Машина 1
    от Black_Cat в разделе Зарубежные компьютеры
    Ответов: 74
    Последнее: 03.03.2009, 09:05
  4. Что за машина такая??? Commodore 128...
    от ILoveSpeccy в разделе Commodore 16/64/128
    Ответов: 5
    Последнее: 31.10.2007, 10:25
  5. Java-машина
    от Error404 в разделе Программирование
    Ответов: 2
    Последнее: 15.01.2007, 15:11

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •