x86-игротека: Скрипт-Инкапсулятор

Тема в разделе "WASM.SOFTWARE", создана пользователем Paguo_86PK, 12 мар 2011.

  1. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    [​IMG]
    Персональный раздел проекта
    Персональный форум проекта

    В общем, сидел вчера и пытался реализовать свою давнюю идею использования x86-инструкций в качестве байт-кода.
    Получился, в общем, очень компактный текст - 160 строчек.
    Работает очень просто: Все операции, напрямую не обращающияся к памяти, остаются как есть. Остальные - модифицируются.
    Так:
    1) Стек отсутствует. Т.е. ESP в шапке x86-кода сохраняется и дальше ESP работает как простой регистр;
    2) Операции PUSH/POP официально не предусмотрены. Хотя транслятор их поддерживает: Извлекает из памяти реальный ESP, производит PUSH/POP, проверяет BOUND ESP и возвращает на место. Операций много, производительность страдает. Но, как уже сказал, операции не предусмотрены концепцией;
    3) Инструкция LEA остаётся как есть. Она же не обращается к памяти, а возвращает вычисленное значение;
    4) Инструкции CALL, JMP, Jcnd и LOOP работают иначе. Вместо переходов по смещению указывается уровень блочной вложенности (break 1-127 / continue 1-127). Так, можно выйти из текущего блока (break 1), из родительского блока текущего (break 2) и т.д. до 127 уровня. Отчего метки попросту отсутствуют и можно строить алгоритм произвольной блочной реализацией. CALL как такового нету, хотя были варианты, такие как
    Код (Text):
    1.     CALL L4    ; Указатель на строку
    2.     CALL L7   ; Вызов API
    3.     ...
    4. L4: db '/dev/con',0 ; где в строке указывается путь к файлу/устройству
    5. L7: db 'SetPixel',0
    но на деле оказалось непрактичным и уязвимым;
    5) Доступа к памяти через указатели не предусмотрено и это запрещено. Вместо ячеек памяти предоставляются готовые структуры. Так, сегменты CS,DS,ES,FS,GS,SS - всего лишь указывают на одну из шести структур, что вполне достаточно. Транслятор же не включает префиксы сегментов в x86-код, но ориентируется по ним для коррекции адреса. Так
    Код (Text):
    1.     MOV  ES,L9 ; Указываем на имя структуры. Здесь - WAVEFORMATEX
    2.     MOV EAX,ES:[3] ; Условный доступ к третьему члену структуры. Здесь - nSamplesPerSec
    3.     MOV ECX,ES:[0] ; Эквивалентно MOV ECX,sizeof(WAVEFORMATEX)
    4.     ...
    5. L9: db '#WAVEFORMATEX',0
    на практике сложно реализуется, по-этому все сегменты - статические и инициализируются при компиляции скрипта. Тем самым, вместо 6 из бесконечного числа структур мы имеем только 6!;
    6) Доступ к памяти без префикса - доступ к локальным переменным. Например:
    Код (Text):
    1.     MOV  EAX,[EDX+0x12345678] ; Эквивалентно EAX = EDX + local_variables[0x12] - local_variables[0x45] ^ 0x78
    ...

    В теории всё более-менее складно. На практике - куча проблем. И проблемы не в самой сложности реализации. А в том, на сколько корректно использовать ссылки на переменные. Т.е. ясно, что ни у какой структуры не может быть 4 млрд. членов. Тогда как распорядиться с этим 32-битным адресом? Усечь количество членов до 256? Не мало ли? А если 65536? Не много ли? А остальные 16-24 бита для чего?
    Т.е. стандарт не выработан...

    В целом, всё более-менее скриптуется и работает с бешенной скоростью. Только вот спец-ассемблер пока не написал. И систему взаимодействия не придумал.
    Так-как скрипт не имеет официального права на какой-либо внешний вызов, вся такая скрипт-программа разбивается на отдельные замкнутые скрипты, где возможен только цикл (и то контроллируется подсчётом тактов процессора). Т.е. пока могу запустить один-другой скрипт. Но вот интегрировать их чем? Текстовым скриптом? Уже парсер нужен...

    В любом случае, идее лет так около пяти. А за реализацию взялся вчера.

    Может кто поделится опытом? Не в плане реализации. А в плане использования 32-битных адресов и т.д.

    Спасибо!
     
  2. artkar

    artkar New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2005
    Сообщения:
    400
    Адрес:
    Russia
    Прочитал по -диагонали ничего не понял, хотя кажется что-то интересное.
    Ты объясни что ты хочешь сделать, цель???
    Обфускатор? Просто сжать код? Где это будет полезно?
     
  3. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    artkar
    это описание ВМ?
     
  4. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Типо, да. Своеобразная VirtualMachine. Правда, подчёркиваю, своеобразная.
    Пока скрипт пишу пользуясь ассемблером HIEW-редактора.
    Главная цель: Проработать концепцию так, чтобы она обгоняла в скорости любые скрипты Flash и Java, а так же имела зачатки конструкций высокоуровневых языков.

    Так, чтобы в любом аудио плеере с DSP-фильтрами можно было использовать собственный скрипт на этом x86-скрипт языке. Скажем, под WinAMP написать DSP-фильтр крошечный с таким компилятором, загрузить его и потом только подставлять в его конфигурации подобные скрипты. Он будет их компилировать и потом передавать управление тому коду.
    Просто давно об этом думал. Чтобы фильтр свой в Visual C++ не нужно было писать каждый раз, а просто в дампе его набросать.
    Скажем, очень полезно для тех, кто не владеет VC или вообще не умеет программировать.
    Допустим, есть он-лайн сервис со скрипт-генератором на заказ пользователя. Тот вводит парочку-другую формул, а сценарий сервера компилирует это в x86-скрипт. Тем самым, получается одновременно и машинный код, и инкапсуляция без возможности подложить вирус!

    То же самое и с фильтрами VirtualDub. Там вообще можно не только видео фильтры писать такими скриптами, сохраняя предельную скорость, но и на лету их модифицировать. Т.е. такой же маленький фильтр с компилятором всегда следит за изменением указанного файла со скриптом. Как только мы скрипт вновь сохраняем, фильтр автоматически читает его, компилирует и передаёт ему управление.
    Если скрипт написан неверно, синтаксически некорректно, фильтр сам сообщит об этом прямо в кадре.

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

    Или анимированный Desktop. Как в WinAMP'е, закрасив рабочий стол OverLay-цветом, можно скриптом на лету проверять любые графические эффекты.

    В общем, спектр применений довольно широкий. Всё от фантазии зависит.
    Я сейчас перечислил лишь несколько их развлекательных направлений. Но умелыми руками можно будет писать всё, от Тетрисов до он-лайн игр или 3D-приложений.
    При этом, сохраняя практически 100% машинной производительности!

    Если идея будет удачной, такие скрипты можно писать не только x86-кодом, но и кодом других процессоров. Без всяких разных Java.
     
  5. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    боюсь, что и тут вас опередили.

    например
    http://ipn.caerwyn.com/2009/01/lab-92-vxinferno.html
    не вчитывайтесь в особенности реализации. просто посмотрите на пример использования сандбокс либы
     
  6. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    Paguo_86PK
    сколько не виртуаль, аппаратно выполняются опкоды ).
     
  7. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Сегодня долго возился с механизмом организации блочной структуры. Будь в основе ассемблер, было бы проще.
    Но здесь, для Break-выходов из блоков, необходимо знать размер блока и где он завершается.
    А это требует либо двух проходов, либо построения таблиц, где надо будет корректировать адреса все ветвлений внутри блока по его закрытию.
    Первое - требует памяти. Второе - сложно и требует ещё больше памяти.
    Решил поступить проще: При открытии блока записывать туда инструкцию выхода из него. Тем самым, все операции выхода из блока ссылаются на неё. А с закрытием блока просто в той инструкции корректируем адрес.
    И вот что получилось:
    Данный скрипт-код
    Код (Text):
    1. B9 10 00 00 00   |MOV  ECX,16
    2. EB 80            |BEGIN
    3. BA 10 00 00 00   |    MOV  EDX,16
    4. EB 80            |    BEGIN
    5. F7 C2 01 00 00 00|        TEST EDX,1
    6. 75 80            |        BEGIN NZ
    7. 03 C3            |            ADD  EAX,EBX
    8. EB 00            |        END
    9. 4A               |        DEC  EDX
    10. 75 00            |    END NZ
    11. E2 00            |END LOOP
    транслируется в
    Код (Text):
    1. B9 10 00 00 00   |    MOV  ECX,16
    2. EB 05            |    JMP  L1
    3. E9 2A 00 00 00   |    JMP  Q1
    4. BA 10 00 00 00   |L1:     MOV  EDX,16
    5. EB 05            |        JMP  L2
    6. E9 19 00 00 00   |        JMP  Q2
    7. F7 C2 01 00 00 00|L2:         TEST EDX,1
    8. 75 05            |            JNZ  L3
    9. E9 02 00 00 00   |            JMP  Q3
    10. 03 C3            |L3:             ADD  EAX,EBX
    11. 4A               |Q3:         DEC  EDX
    12. 75 02            |        JNZ  C2
    13. EB 05            |        JMP  Q2
    14. E9 E7 FF FF FF   |C2:     JMP  L2
    15. E2 02            |Q2: LOOP C1
    16. EB 05            |    JMP  Q1
    17. E9 D2 FF FF FF   |C1: JMP  L1
    18.                  |Q1:
    и благополучно работает.
    Правда, выгладит безобразным лабиринтом. Но на данной стадии развития концепции это подойдёт.
     
  8. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    Paguo_86PK
    все понятно, кроме одного - почему

    MOV EDX,16

    разве это удобно? вы ж все равно транслируете. почему не

    r3 = 16
    r3 += 2
    r3:r0 *= r1
    << r3

    помойму, все нагляднее и короче

    ворд от дворда - r3w, дворды - r3bh и r3bl итд

    еще неплохо бы както симметризовать x86. чтоб все полностью интуитивно было
     
  9. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Хм. Я понял, Вы предлагаете переименовать регистры.
    Как я сказал, на данном этапе с работой в Hiew-редакторе, имена регистров трогать не следует. Для таких целей нужно писать уже собственный ассемблер и к нему - подобие Си--, на свой js-вариант которого я давал ссылку некогда...
    С именами регистров я вообще делал вариант:
    Код (Text):
    1. ; Здесь:
    2. ; EAH -> HIWORD(EAX)
    3. ; EAL -> LOWORD(EAX) or AX
    4. ; EDH -> HIWORD(EDX)
    5. ; EDL -> LOWORD(EDX) or DX
    6. ; В одной из тем я уже писал об этом.
    7. ; Тогда:
    8. ; Имеем запись x86-скрипта:
    9. 66 12 E2    ADC EAH,EDL        ; Сложить старшую половину EAX с младшей EDX
    10. ; необходимо переобразовать в нечто подобное:
    11.     XCHG    ESP,[real_stack]   ; Нам понадобится стек!
    12.     PUSH    WORD 0x0000        ; Первые 16-бит - 0
    13.     PUSH    DX                 ; Старшие - DX
    14.     ADC     EAX,[ESP]          ; Указанная операция
    15.     LEA     ESP,[ESP+4]        ; Удаляем из стека. LEA не влияет на флаги!
    16.     XCHG    ESP,[real_stack]   ; Восстанавливаем ESP
    А такие конструкции, как 66 12 .. ни один ассемблер/дизассемблер не переваривает.
    Сейчас же, когда с блочными механизмами практически разобрался, нужно обязательно разрабатывать именно свой ассемблер с перевариванием и таких регистров.
    Набор полный регистров получается таким: EAX(EAH:EAL(AH:AL)), ECX(ECH:ECL(CH:CL)), EDX(EDH:EDL(DH:lol: L)), EBX(EBH:EBL(BH:BL)), ESP, EBP, ESI, EDI.
    Так что переименовывать их будет не просто. Например:
    Код (Text):
    1. EAX -> ABC | EAH -> A | EAL -> BC | AH -> B | AL -> C
    2. ECX -> IJK | ECH -> I | ECL -> JK | CH -> J | CL -> K
    3. EDX -> XYZ | EDH -> X | EDL -> YZ | DH -> Y | DL -> Z
    4. EBX -> LMN | EBH -> L | EBL -> MN | BH -> M | BL -> N
    5. ESP -> S
    6. EBP -> P
    7. ESI -> Q
    8. EDI -> R
    вариант довольно кривой и не интуитивный с непривычки.
    Хотя скрипт писать без всяких Hi-Lo-половинок практичнее. Нужно лишь проработать как следует систему имён регистров. Буду рад содействию.
    А всякие r3w r2l - из ряда RISC-технологий. Тяжело запомнить в скрипте назначения проиндексованных регистров. Легче I(iterrator) - ECX, XY(position) - EBX, R(result) - EAX и т.д. Но всё это надо продумать хорошо и складно...
     
  10. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    зачем вам какоето кривое С-- ? если уж вы сочиняете вариацию языка, ассемблера или нет - не важно, то освойте какой нибудь генератор компиляторов/интерпретаторов. увидите, что особой проблемы написать компилер или интерпрер для вашего языка нету.
    а зачем вам чтото запоминать? просто предусмотрите именование. а однородное называние однородных частей очень упрощает запоминание и работу. попробуйте сами.

    можно еще рассмотреть регистр как структуру из меньших частей, те

    r1 -> r1.h r1.l -> r1.l.h r1.l.l

    можно включить разные представления. например

    r1.w.l или r1.b.3 . итд.

    если уж фантазировать, то фантазировать. например, посмотрите до чего дофантазировался один товарищ насчет avr ассемблера http://www.algrom.net/russian.html
     
  11. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Да, хороши ссылочки! Бр-ррр...
    Жуть. ИМХО, не мой уровень.
    Хоть то, что я сейчас делаю, и может показаться запутанным и сложным, на самом деле весит уже всего 285 Си-строк. Немного поработать, появится поддержка и FPU, и MMX. Но меня сейчас волнует вопросы, с которых я и начал тему: Адресация данных и интеграция нескольких скриптов.

    Вообще в качестве примера, вы не поверите, я использовал концепцию паттернов трекерной музыки. Тем самым, так или иначе, у меня скрипт - паттерн. А значит нужно продумать механизм снятие результата работы одного скрипта и передачи этих данных в другой.
    Помните пассивный процессор? Какрас в нём я пытался проработать этот механизм.

    Кстати, бью транслятор и вдруг понимаю, что в начале любого блока могу организовать приостановку скрипт по временному условию, а потом продолжить работу с точки разрыва. А значит, несколько скриптов по-очереди могут работать независимо друг от друга продолжительный период! Ну, а толку то? Если нет концепции некоего скрипта-супервизора...

    Надо бы серъёзнее взяться за вопрос... Хотя, как я говорил выше, для DSP-фильтрации или видео-эффектов достаточно одного скрипта.
    С одной стороны, довольно одного скрипта и не нужно больше ничего ухищрять. А с другой, следовало бы предусмотреть и возможность строить сеть таких скриптов для решения более сложных задач.
    Короче, сам себя запутал!

    Поставлю пока такие сверх-задачи:
    1) Объявление входных-выходных массивов, с чем я таки и бьюсь;
    2) Перезагрузку имён регистров. Хотя, чушь, вьювер ещё не написан же...
     
  12. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    Paguo_86PK
    это вы про это?
    http://www.thinq.co.uk/2010/11/22/intel-launches-fpga-equipped-atom/
     
  13. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Хм... Помнится, все смеялись над этой моей задумкой... А теперь, сама Intel! Ну, значит, я тут, как говорит Зелёный из "Тайны третьей планеты": Здесь мне делать нечего...

    Кстати, я забыл сказать, что проект данной темы - приложение к соседней. А если копать глубже, то первые шаткие шаги к реализации концепции моей OS...

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

    1) Вместо драйверов - x86-скрипты. Клавиатура, звук, дисплей - всё в скриптах;
    2) Оболочка (интерфейсы, обозреватели и т.д.) - всё x86-сценарии, как в Windows файлы .htt для папок;
    3) Все исполняемые файлы (драйверы/приложения) - всегда каждый в своём .tar.gzip архиве. Т.е. специальных форматов файлов (как dll/lib/obj/so) в принципе нет. Большое приложение представляет большой .tar с кучей скриптов и сценариев, а так же ресурсов (подобия .res) во вложенных .tar: Звуковой поток, картинка, иконка - всё тот же .tar, но с файлами .raw (дамп чего угодно: видео/аудио) и .dec (декларация/описание ресурса как .ini или .conf) в текстовом виде с иерархией и ссылками на драйвер (например /dev/audio), чтобы OS сама не угадывала, а сразу передала на обработку нужному драйверу...

    Здесь x86-сценарий на уровень выше x86-скрипта. Как я уже говорил выше, несколько скриптов связять в один (сценарий) для меня сейчас проблема. Стандарт не разработан вообще.
    Ясно только одно. Сейчас я копаюсь с решением 1). До остальных пунктов очень далеко...
     
  14. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    В общем, с теорией удалось более-менее разобраться. На данный момент исправно работает следующий пример:
    Код (Text):
    1. for(long ecx = 256; ecx; -- ecx)
    2.     for(long edx = 256; edx; -- edx)
    3.         SetPixel(hdc, edx, ecx, GetPixel(hdc, edx, ecx) + 0x030201);
    который представляется как:
    Код (Text):
    1. ; x86-Assembler                              ; x86-Script
    2. MOV     DS,szGDI                            |INCLUDE DS,"/dev/gdi"
    3. JMP     $-128                               |BEGIN
    4.   MOV     ECX,256                           |  MOV     ECX,256
    5.   JMP     $-128                             |  BEGIN
    6.     MOV     EDX,256                         |    MOV     EDX,256
    7.     JMP     $-128                           |    BEGIN
    8.       LOCK                                  |      LOCK
    9.       MOV     EAX,DS:[ECX][EDX][szGetPixel] |      MOV     EAX,DS.GetPixel(EDX,ECX)
    10.       ADD     EAX,0x00030201                |      ADD     EAX,0x00030201
    11.       LOCK                                  |      LOCK
    12.       MOV     DS:[ECX][EDX][szSetPixel],EAX |      MOV     DS.SetPixel(EDX,ECX),EAX
    13.       DEC     EDX                           |      DEC     EDX
    14.     JNE     $+0                             |    END     NE
    15.   LOOP    $+0                               |  END     LOOP
    16. JMP     $+0                                 |END
    17. HLT                                         |HLT
    18. szGDI      DB  '/dev/gdi',0
    19. szGetPixel DB  'GetPixel',0
    20. szSetPixel DB  'SetPixel',0
    и компилируется в
    Код (Text):
    1. 00439B62 60                   pushad
    2. 00439B63 9C                   pushfd
    3. 00439B64 89 25 98 9A 43 00    mov         dword ptr [ScriptCode (00439a98)],esp
    4. 00439B6A BC A4 9A 43 00       mov         esp,offset ScriptCode+0Ch (00439aa4)
    5. 00439B6F 9D                   popfd
    6. 00439B70 61                   popad
    7. 00439B71 8B 25 B4 9A 43 00    mov         esp,dword ptr [ScriptCode+1Ch (00439ab4)]
    8. 00439B77 FF 25 A0 9A 43 00    jmp         dword ptr [ScriptCode+8 (00439aa0)]
    9. 00439B7D 89 25 C8 9A 43 00    mov         dword ptr [ScriptCode+30h (00439ac8)],esp
    10. 00439B83 BC C8 9A 43 00       mov         esp,offset ScriptCode+30h (00439ac8)
    11. 00439B88 60                   pushad
    12. 00439B89 9C                   pushfd
    13. 00439B8A 8B 25 98 9A 43 00    mov         esp,dword ptr [ScriptCode (00439a98)]
    14. 00439B90 FF 35 C8 9A 43 00    push        dword ptr [ScriptCode+30h (00439ac8)]
    15. 00439B96 8F 05 B4 9A 43 00    pop         dword ptr [ScriptCode+1Ch (00439ab4)]
    16. 00439B9C 9D                   popfd
    17. 00439B9D 61                   popad
    18. 00439B9E C3                   ret
    19. 00439B9F EB 05                jmp         ScriptCode+10Eh (00439ba6)
    20. 00439BA1 E9 00 00 00 00       jmp         ScriptCode+10Eh (00439ba6)
    21. 00439BA6 B9 00 01 00 00       mov         ecx,100h
    22. 00439BAB EB 05                jmp         ScriptCode+11Ah (00439bb2)
    23. 00439BAD E9 C6 00 00 00       jmp         ScriptCode+1E0h (00439c78)
    24. 00439BB2 BA 00 01 00 00       mov         edx,100h
    25. 00439BB7 EB 05                jmp         ScriptCode+126h (00439bbe)
    26. 00439BB9 E9 B1 00 00 00       jmp         ScriptCode+1D7h (00439c6f)
    27. 00439BBE 89 25 C8 9A 43 00    mov         dword ptr [ScriptCode+30h (00439ac8)],esp
    28. 00439BC4 BC C8 9A 43 00       mov         esp,offset ScriptCode+30h (00439ac8)
    29. 00439BC9 60                   pushad
    30. 00439BCA 9C                   pushfd
    31. 00439BCB 8B 25 98 9A 43 00    mov         esp,dword ptr [ScriptCode (00439a98)]
    32. 00439BD1 FF 35 C8 9A 43 00    push        dword ptr [ScriptCode+30h (00439ac8)]
    33. 00439BD7 8F 05 B4 9A 43 00    pop         dword ptr [ScriptCode+1Ch (00439ab4)]
    34. 00439BDD 9D                   popfd
    35. 00439BDE 61                   popad
    36. 00439BDF FF 35 BC 9A 43 00    push        dword ptr [ScriptCode+24h (00439abc)]
    37. 00439BE5 FF 35 C0 9A 43 00    push        dword ptr [ScriptCode+28h (00439ac0)]
    38. 00439BEB FF 35 9C 9A 43 00    push        dword ptr [ScriptCode+4 (00439a9c)]
    39. 00439BF1 E8 65 37 AE 77       call        77F1D35B
    40. 00439BF6 A3 C4 9A 43 00       mov         [ScriptCode+2Ch (00439ac4)],eax
    41. 00439BFB 60                   pushad
    42. 00439BFC 9C                   pushfd
    43. 00439BFD 89 25 98 9A 43 00    mov         dword ptr [ScriptCode (00439a98)],esp
    44. 00439C03 BC A4 9A 43 00       mov         esp,offset ScriptCode+0Ch (00439aa4)
    45. 00439C08 9D                   popfd
    46. 00439C09 61                   popad
    47. 00439C0A 8B 25 B4 9A 43 00    mov         esp,dword ptr [ScriptCode+1Ch (00439ab4)]
    48. 00439C10 05 01 02 03 90       add         eax,90030201h
    49. 00439C15 89 25 C8 9A 43 00    mov         dword ptr [ScriptCode+30h (00439ac8)],esp
    50. 00439C1B BC C8 9A 43 00       mov         esp,offset ScriptCode+30h (00439ac8)
    51. 00439C20 60                   pushad
    52. 00439C21 9C                   pushfd
    53. 00439C22 8B 25 98 9A 43 00    mov         esp,dword ptr [ScriptCode (00439a98)]
    54. 00439C28 FF 35 C8 9A 43 00    push        dword ptr [ScriptCode+30h (00439ac8)]
    55. 00439C2E 8F 05 B4 9A 43 00    pop         dword ptr [ScriptCode+1Ch (00439ab4)]
    56. 00439C34 9D                   popfd
    57. 00439C35 61                   popad
    58. 00439C36 FF 35 C4 9A 43 00    push        dword ptr [ScriptCode+2Ch (00439ac4)]
    59. 00439C3C FF 35 BC 9A 43 00    push        dword ptr [ScriptCode+24h (00439abc)]
    60. 00439C42 FF 35 C0 9A 43 00    push        dword ptr [ScriptCode+28h (00439ac0)]
    61. 00439C48 FF 35 9C 9A 43 00    push        dword ptr [ScriptCode+4 (00439a9c)]
    62. 00439C4E E8 8E 37 AE 77       call        77F1D3E1
    63. 00439C53 60                   pushad
    64. 00439C54 9C                   pushfd
    65. 00439C55 89 25 98 9A 43 00    mov         dword ptr [ScriptCode (00439a98)],esp
    66. 00439C5B BC A4 9A 43 00       mov         esp,offset ScriptCode+0Ch (00439aa4)
    67. 00439C60 9D                   popfd
    68. 00439C61 61                   popad
    69. 00439C62 8B 25 B4 9A 43 00    mov         esp,dword ptr [ScriptCode+1Ch (00439ab4)]
    70. 00439C68 4A                   dec         edx
    71. 00439C69 0F 85 4F FF FF FF    jne         ScriptCode+126h (00439bbe)
    72. 00439C6F E2 02                loop        ScriptCode+1DBh (00439c73)
    73. 00439C71 EB 05                jmp         ScriptCode+1E0h (00439c78)
    74. 00439C73 E9 3A FF FF FF       jmp         ScriptCode+11Ah (00439bb2)
    75. 00439C78 C7 05 A0 9A 43 00 00 mov         dword ptr [ScriptCode+8 (00439aa0)],0
    76. 00439C82 E9 F6 FE FF FF       jmp         ScriptCode+0E5h (00439b7d)
    Здесь префикс LOCK указывает на непосредственно включение кода вызова функции в код скрипта.
    Иначе скрипт будет приостанавливаться для интерпретации вектора операции. Код при этом выглядит вот так:
    Код (Text):
    1. 00439BC0 C7 05 A0 9A 43 00 CF mov         dword ptr [ScriptCode+8 (00439aa0)],offset ScriptCode+137h (00439bcf)
    2. 00439BCA E9 AE FF FF FF       jmp         ScriptCode+0E5h (00439b7d)
    3. 00439BCF 8B 84 11 .. .. .. .. mov         eax,dword ptr [ecx+edx+...]
    4. 00439BD6 05 01 02 03 90       add         eax,90030201h
    5. 00439BDB C7 05 A0 9A 43 00 EA mov         dword ptr [ScriptCode+8 (00439aa0)],offset ScriptCode+152h (00439bea)
    6. 00439BE5 E9 93 FF FF FF       jmp         ScriptCode+0E5h (00439b7d)
    7. 00439BEA 89 84 11 .. .. .. .. mov         dword ptr [ecx+edx+...],eax
    К тому же, почти разобрался с проблемой интеграции скриптов. На данный момент пока не реализовано, но уже решено, что другие скрипты будут подключаться декларацией '/scp/...' и работать как обычные функции.

    Со стороны посмотреть - ужасный код. Нужно будет копать в сторону CreateProcess и VDMCONTEXT, о которых я очень мало знаю на настоящий момент...

    [o]* * *[/o]
    Итак, продолжая углубляться в развитие x86-скриптов.
    Согласно идеалогии x86-скриптов, а именно, использования машинного x86-кода в качестве байт-кода псевдо-виртуальной машины, все вычислительные инструкции кодируются как есть. За исключением векторов памяти, которые переназначаются строго в соответствиях правил безопасности. А так же, работа с сегментными регистрами, о которых давно забыли в прикладном программировании многих операционных систем, также активно задействована.
    Так, рассмотрим следующий пример:
    Код (Text):
    1.     JMP     $-128                      |BEGIN   ; <- First-sub-script biginning   <────────────┐
    2.       MOV     DX,DS                    |  MOV     EDX,Z                                        │
    3.       MOV     BP,ES                    |  MOV     EBP,Y                                        │
    4.       MOV     BX,GS                    |  MOV     EBX,X                                        │
    5.       MOV     CX,CS                    |  MOV     ECX,N                                        │
    6.       MOV     SP,SS                    |  MOV     ESP,L                                        │
    7.       MOV     AX,FS                    |  MOV     EAX,M                                        │
    8.       TEST    AH,0xFF                  |  TEST    AH,0xFF     ; if(simple) {                   │
    9.       JZ      $-128                    |  BEGIN   Z           ;   switch(AL) {                 │
    10.         CMP     AL,0x88                |    CMP     AL,0x88                                    │
    11.         JZ      $-128                  |    BEGIN   Z         ;   case "MOV mem8,reg":         │
    12.           ...                          |      ...             ;     ...                        │
    13.           JMP     $-3                  |      BREAK   3 ────┐ ;     return;                    │
    14.         JMP     $+0                    |    END             │ ;     break;                     │
    15.         CMP     AL,0x8A                |    CMP     AL,0x8A │                                  │
    16.         JZ      $-128                  |    BEGIN   Z       │ ;   case "MOV reg,mem8":         │
    17.           ...                          |      ...           │ ;     ...                        │
    18.           JMP     $-3                  |      BREAK   3 ────┤ ;     return;                    │
    19.         JMP     $+0                    |    END             │ ;     break;                     │
    20.         JMP     $-2                    |    BREAK   2 ────┐ │ ;   }                            │
    21.       JMP     $+0                      |  END             │ │ ; } else                         │
    22.       CMP     AL,0xAC                  |  CMP     AL,0xAC │ │ ; switch(AL) {                   │
    23.       JZ      $+0                      |  BEGIN   Z       │ │ ; case "SHRD mem32,reg,n":       │
    24.         ...                            |    ...           │ │                                  │
    25.         JMP     $-2                    |    BREAK   2 ────┤ │ ;   break;                       │
    26.       JMP     $+0                      |  END             │ │ ; }                              │
    27.     JMP     $+0                        |END     <═════════╧─┘ ; <- End of first-sub-script     │
    28.     JMP     $-128                      |BEGIN                 ; <- Second-sub-script biginning │
    29.       ...                              |  ...                                                  │
    30.     JMP     $+0                        |END                   ; <- End of second-sub-script    │
    31.     JMP     $-128                      |BEGIN                 ; <- Main script                 │
    32.       MOV     ES,[L1]                  |  INCLUDE ES,"/scp/:1"                                 │
    33.       MOV     EDX,0x20454458           |      MOV     EDX,0x20454458                           │
    34.       MOV     EBX,0x20454258           |      MOV     EBX,0x20454258                           │
    35.       MOV     EBP,0x20454250           |      MOV     EBP,0x20454250                           │
    36. SHRD ES:[EBP][EBX*4][0x12345678],EDX,23|  SHRD ES:[EBP][EBX*4][0x12345678],EDX,23 ─────────────┘
    37.     JMP     $+0                        |END
    38.     HLT                                |HLT                   ; <- Script end
    39. L1: DB  '/scp/:1',0
    Здесь видно, что обращение к памяти через вектор [EBX][EDX*4][0x12345678] вызывает под-скрипт текущего файла, а все операнды команды получают зеркала в виде сегментных регистров:
    Код (Text):
    1. ; EDX=0x20454458
    2. ; EBX=0x20454258
    3. ; EBP=0x20454250
    4. ; Flags=11000111
    5. 0F AC 94 9D 78 56 34 12 17    |SHRD    [EBP][EBX*4][0x12345678],EDX,23
    6. -----------------------------> M       [Y][X*M][L],Z,N
    7. -----------------------------> FS      [ES][GS*FS][SS],DS,CS
    8. Virtual Y or ES=0x20454250: Base register
    9. Virtual N or CS=0x00000017: Instruction data
    10. Virtual L or SS=0x12345678: Label/Displace
    11. Virtual Z or DS=0x20454458: Source/Destination register
    12. Virtual M or FS=0xC7800FAC: Flags & Multiplicator (1,2,4,8) & Instruction code
    13. Virtual X or GS=0x20454258: Index register
    Значения реальных регистров заносятся напрямую в рабочую область вызываемого скрипта, а по-завершению - считываются обратно в регистры текущего скрипта. Тем самым, ни один из скриптов не может знать реально указанных регистров, но может изменять их.
    Исключения представляют инструкции работы со строкой, где регистры ESI, EDI и ECX (при REPcnd) также доступны по-умолчанию. Таким простым способом построено всё взаимодействие скриптов.

    У каждого скрипта имеется своя маленькая статическая память объёмом до 256 ячеек. Они доступны по векторам [EBP-128]..[EBP+127].
     
  15. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    [​IMG]
    Итак. Можно подвести некоторые итоги моей работы.
    Вот текущая версия Windows-оболочки и он-лайн редактор dump'а с дизассемблером.
    Так же стало доступным:
     •  Персональный раздел проекта
     •  Персональный форум проекта

    На текущий момент разработаны некоторые правила структуры x86-скриптов:
     •  В одном файле допускается до 256 под-скриптов;
     •  Каждый под-скрипт начинается открытием блока с помощью BEGIN или HOOK;
     •  BEGIN-открытый скрипт работает как функция и имеет свой порядковый индекс "/app.#n";
     •  HOOK-открытый скрипт служит для внедрения в системный процесс (окраска заголовка окна, события мыши и клавиатуры);
     •  Главный скрипт описывается всегда в конце.

    Так, допустим, нам надо окрашивать поверхность окна (WM_ERASE) своим способом. Объявляем Hook на нужное событие и всё. Сам по-себе Hook не доступен другим скриптам. Но когда приложение начнёт закраску окна и обнаружит наличие Hook'а на это событие, то каждый пиксел окна будет окрашиваться цветом, возвращаемым в Hook-скрипте.

    На практике получаются очень сильные тормоза, из-за GetPixel/SetPixel. Однако, расчёт же на то, что концепция скриптов взята из идеологии самой операционной системы. А значит они должны внедряться прямо в системный код с доступом к видео памяти.

    Так что, пока как могу, занимаюсь реализацией.
     
  16. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Нет конца моей глупости, оказывается!
    На одном форуме заметили, что я изобрёл самый настоящий велосипед - Шейдеры, только под x86!
    Хм. А ведь раньше я и понять никак не мог, что за шейдеры такие в современных видео адаптерах?
    Получается, ещё в 1997, когда я сидел ещё за XT-совместимом в DOS 3.1, уже тогда задумывался о подобных технологиях? Странно.
    Действительно, почему в Windows нету Шейдеров? Чтобы, скажем, внешний интерфейс выглядил как в MacOS, нужно ставить всякие WinBlings и Astone. Тогда как можно было просто описать вид в скрипте.
    Хм. Замачиво, по-крайней мере, для меня. Вот тому-то я и занялся этими x86-скриптами. А ныне - x86-шейдерами.
     
  17. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Paguo_86PK
    Что за бред вы снова несёте? Какие шейдеры, какая Windows? Невозможно ничего понять.
     
  18. Paguo_86PK

    Paguo_86PK Руслан

    Публикаций:
    0
    Регистрация:
    8 окт 2007
    Сообщения:
    911
    Адрес:
    Ташкент
    Шейдеры - не моя идея. На одном из форуме меня поздравили с изобретением велосипеда: Шейдеров под Виндовс.
    Именно тогда я зашёл в википедию и подробно прочитал про Шейдеры. И действительно, сходство есть.