![]() |
создание MIDletPascal compiler'a
Вложений: 1
Есть предложение, на сайте http://compilers.da.ru/ есть описание компилятора Pascal <PASCALS.ZIP>, который создает стековый байт-код.
Этот исходник можно адаптировать под запись java-кода. Только нужно полное описание java-byte-code и формата class-файлов. В данный момент у меня работа и редко доступ к интернету, потому самому не осилить... (если Компилятор получиться, то он будет создавать код не хуже MIDletPascal, а размером будет не более 200кб). C уважением IronWoodcutter. |
Ответ: создание MIDletPascal compiler'a
P.S. кто сможет помочь пишите на [email protected]
|
Re: создание MIDletPascal compiler'a
Во первых компилятор старый и под свою виртуальную машину, во вторых для компилера для JVM надо описание байт кода JAVA или хотябы (в случае транслятора) хорошее знание JAVA...
|
Ответ: создание MIDletPascal compiler'a
Для знания структуры Java-class файла надо покупать там какую-то лицензию и тебе предоставят документацию. Причем лицензий этих несколько видов, причем по разным ценам. Этим, кстати, и объясняется то, что разные Java декомпиляторы (DJ, Cavaj, JavaDec) допускают одинаковые ошибки при декомпиляции. Просто они все созданы на основе дешевой лицензии, а для знания некоторых конструкций уже надо более продвинутая. По-этому ждать когда же они будут нормально декомпилить пустая трата времени. Надо было сразу перед созданием проекта раскошелиться на более приличную сумму.
|
Ответ: создание MIDletPascal compiler'a
Давайте скинемся всем форумом и купим полную лицензию =)
|
Ответ: создание MIDletPascal compiler'a
Мы же не американцы, чтобы что то покупать. Давайте лучше стырим! :crazy:
А если серьезно, я бы пожертвовал несколько долларов для общего дела. Но только несколько :) |
Ответ: создание MIDletPascal compiler'a
Я бы и десятку пожертвовал :-D
|
Re: создание MIDletPascal compiler'a
Да тырить не надо ничего, все есть, я уже ж подымал тему. Надо знание двух языков Java (для выдергивания байт кода из компилятора который написан на Java) и Pascal-Delphi для оформления самого копмилятора (PE файл), остальное все пишется оч быстро, вернее уже написан (в часности и я писал компилеры), поэтому если интузиазм есть и желание, могу рассказать и показать как пишеца компилер (любой), в добавок потом можно из него сделать оптимизирующий.
|
Ответ: создание MIDletPascal compiler'a
можно попробовать сделать шаблон для инициализирующих и завершающих секций class-файла, а внутрь добавлять скомпилированный java-код, или же поступить по принципу MIDletPascal заготовить стартующий класс, а к нему дополнительный простого формата class с кодом...
|
Ответ: создание MIDletPascal compiler'a
MIDletPascal совсем не оптимизирует созданнй код, пишет его как есть, идея создания компилятора ограничивается, возможно только созданием консольной версии, которая сможет создавать class -файлы, т.е. среда_разработки/упаковка/эмулятор - это внешне программы.
Можно сделать в отдельном файле список функций их параметры, чтоб при компиляции проверять исходный текст, т.е. как описываются в Delphi интерфейсы API |
Ответ: создание MIDletPascal compiler'a
исходник компилятора, который представил - один из самых простых, грамотно написанных, небольших и в тоже время достаточно функциональный, среди всех которые мне встречались.
Поэтому если его преобразовать,-это будет отличное решение компилятора в исходных кодах, предназначенный для компиляции MIDlet'ов |
Re: создание MIDletPascal compiler'a
Ладн не будем спорить. Так вот надо решить прежде, что писать то? Компилер или транслятор с Pascal в Java. И в том и том случае лучше пользоваца методом рекурсивного спуска/подъёма с конвертацией выражений в польскую запись. Короче если чо надо, всегда помогу, кстати IDE а ля Delphi 2007 могу предоставить (вернее качаем тут ->
http://sharing.ho.com.ua/freeide/ide.zip сама IDE (212.19кб) http://sharing.ho.com.ua/freeide/cmp.zip компоненты (196.45кб) http://sharing.ho.com.ua/freeide/bin.zip бинарный файл (414.71кб) ), что бы не було проблем устанавливаем TurboDelphi и тыкаем в неё компоненты... В ней уже основные опции есть, подсветку тока перестроить у меня там на Fasm и D настроено, так же поддержка шаблонов. Описание компонентов могу отыскать, они у меня с Круглого стола по моему... Короче если вы действительно на полном серьёзе хотите создать свой MP токда abcdef сбирай идиномышлеников и в путь... |
создание MIDletPascal compiler'a
Вложений: 2
Вот документация, которая есть у меня по java-коду, но этого не достаточно, нужны хотя бы некоторые сходные примеры подобных программ (компилеры/декомпилеры java и т.д.).
Кто может, пожайлуста выкладывайте доку и исходники, не важно на каком языке (pascal/c/java) и ссылку на страничку откуда это было скачано... а то просто мало свободного времени и очень плохой канал с интернетом Заранее спасибо! |
Re: создание MIDletPascal compiler'a
Так стоп. Во первых сгоняй на http://forum.boolean.name/showthread.php?t=6028&page=3
там качни Canterbury Pascal for J2ME.В нем отыщи файл SYSTEM.pas. Это уже готовый компилятор в байт код, единственное его переработать под Delphi (просто он там использует Java библиотеки), шаблонные функции в IDE есть... Вот и все дела... У меня тож с интернетом какай та херня севодня, поетому сложновато общаца... |
Ответ: создание MIDletPascal compiler'a
он и так с Дельфи 2, совместимый.
|
Ответ: создание MIDletPascal compiler'a
спасибо! это уже что-то, хотя решение не простое, и нужно ставить java.
буду смотреть... при беглом просмотре скачанных файлов меня заинтересовали исходники, т.е. *.class-файлы ;) из каталога pascal.zip/pascal/pas3/mhc/compiler/ P.S. можно конечно сделать конвертирощик из pascal-исходника в java-исходник, но идея состоит именно в получении готового *.class-файла без дополнительных утилит и программ |
Re: создание MIDletPascal compiler'a
Тогда вот пример создания PE файла, расписана почти вся структура, короче прилепить суда тока Синт. и Лексич. анализаторы и готов компилер в exe.
http://sharing.ho.com.ua/freeide/test.zip бинарный файл (5.45кб) Ща поднимаю форматы class файлов, но по памяти там вроде все в массивы запихнуто, типа 0х00 Массив структур 0х20 Массив классов ......................... Помню что там чота оч простое. Потом хорошоб достать Java декомпилер (ща пробую исходники достать) А вообще надо с автором MP насчет исходников как то связаца. http://www.uni-vologda.ac.ru/java/jvm/outline.htm На русском и формат CLASS и спецификация... |
Ответ: создание MIDletPascal compiler'a
satan сенкс, активное участие и за последнюю ссылку! правда в доке что я выкладывал написано то же, но на английском...
С PE заголовками думаю не стоит лезть в дебри, компилятор делфы, или другой сам все сделает, мы же не соревнуемся в создании самого маленького компилятора )) |
Re: создание MIDletPascal compiler'a
Ну да... просто я к тому, что в принципе база для создания всего что нужно уже есть, причом CLASS файлы луче создавать именно массивом а не структурами, так как это работает в несколько сот раз быстрее... Гы...
Ну чо, изучаем тогда.... помалень... |
Ответ: создание MIDletPascal compiler'a
Товарищ которому авторы МР отдали исходники как в воду канул. Не появляется на форуме и на личку не отвечает.
|
Ответ: создание MIDletPascal compiler'a
Если товарищ хотел непомню сколько $ за регистрацию,.. то врятли отдаст исходники, даже за зеленые...
|
Ответ: создание MIDletPascal compiler'a
Он их уже отдал. Они там хотели их под GPL выложить и пропали.
|
Re: создание MIDletPascal compiler'a
Пора видать мне на форуме отписать все что я о пиндосах думаю... Но ет лирика
Короче дуем для начала на http://www.febooti.com/products/file...rs/hex-editor/ там много всего вкусного, но нам нужен HEX editor (он прям в свойства прописывается и данные копируюца в текстовом формате) Итак чо я посмотрел и проверил... Значицо для начала компильнул класс типа class HelloWorld{ public static void main(String [] args){ System.out.println("Hello World!"); } } с помощью jikes.exe и получил байткод CA FE BA BE 00 00 00 30 00 1D 01 00 0A 48 65 6C 6C 6F 57 6F 72 6C 64 07 00 01 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 07 00 03 01 00 04 6D 61 69 6E 01 00 16 28 5B ................................... весь не привожу сами увидите, ну что открываем спецификацию и пробуем разобраться ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; ........................... Разбиваем наш БК как я понял u2..u4 это кол-во байт, и согласно этому получаем CA FE BA BE // MAGIC - магическое число u4(4 байта) 00 00 // Minor version - младшая версия Java u2(2 байта) 00 30 // Major version - старшая версия Java u2(2 байта) 00 1D // Constant_pool_count u2(2байта) .................................... Так вот ребята, у кого старшая версия компилера (4.5) проверте мое предположение насчот u1..u2..u4 типов, если я прав, то тогда попробую расписать полностью формат CLASS файла по смещениям, потом попробуем в ручную создать, прям в байт-коде простенькое приложение, и если получица, будем хренарить уже компилер... ЗЫ... Магическое число прикольное - Кафе бабе, прям как у нас Кабак и Бабы :D |
Ответ: создание MIDletPascal compiler'a
эх, прийдется все вручную делать...
вообщем вот выдрал список всех java-команд из моего отправленного файла: byte_code.zip, и список команд, используемых в предложенном компиляторе Паскаля... сразу говорю что не все команды будут использоваться... многие из них это упрощенные константные команды начинать надобы с простенького ассеблера, на мой взгляд лучше сделать два массива (или области памяти), 1-для записи структур заголовка, 2-й - для записи байт-кода... а еще лучше под каждую структуру заголовка отдельный массив... т.к. компилятор однопроходный, а при разборе текста программы будут добавляться новые вызываемые методы, т.е. заголовок будет расти... после компиляции заголовок а затем код сбрасываются в файл _________ add = 0; { opcodes } neg = 1; mul = 2; divd = 3; remd = 4; div2 = 5; rem2 = 6; eqli = 7; neqi = 8; lssi = 9; leqi = 10; gtri = 11; geqi = 12; dupl = 13; swap = 14; andb = 15; orb = 16; load = 17; stor = 18; hlt = 19; { terminate program } stop = 20; { end of code } wri = 21; wrc = 22; wrl = 23; rdi = 24; rdc = 25; rdl = 26; eofi = 27; { check eof } eol = 28; ldc = 29; lda = 30; { load address } ldla = 31; ldl = 32; ldg = 33; stl = 34; stg = 35; move = 36; copy = 37; addc = 38; mulc = 39; jump = 40; jumpz = 41; call = 42; adjs = 43; sets = 44; exit = 45; --------------------- aconst_null = 1; //Загрузка в стек null ( пустой ссылки на объект) iconst_m1 = 2; //Загрузка целочисленной константы -1 iconst_0 = 3; //Загрузка целочисленной константы 0 iconst_1 = 4; //Загрузка целочисленной константы 1 iconst_2 = 5; //Загрузка целочисленной константы 2 iconst_3 = 6; //Загрузка целочисленной константы 3 iconst_4 = 7; //Загрузка целочисленной константы 4 iconst_5 = 8; //Загрузка целочисленной константы 5 lconst_0 = 9; //Загрузка длинной целочисленной константы 0 lconst_1 = 10; //Загрузка длинной целочисленной константы 1 fconst_0 = 11; //Загрузка вещественного числа одинарной точности 0 fconst_1 = 12; //Загрузка вещественного числа одинарной точности 1 fconst_2 = 13; //Загрузка вещественного числа одинарной точности 2 dconst_0 = 14; //Загрузка вещественного числа двойной точности 0 dconst_1 = 15; //Загрузка вещественного числа двойной точности 1 bipush = 16; //1,Загрузка в стек однобайтового целого со знаком sipush = 17; //2,Загрузка в стек двухбайтового целого со знаком ldc1 = 18; //1,Загрузка в стек элемента из константного пула ldc2 = 19; //2,Загрузка в стек элемента из константного пула ldc2w = 20; //2,Загрузка в стек длинного целого или двойного вещественного значения из константного пула iload = 21; //1,Загрузка целого из локальной переменной lload = 22; //1,Загрузка длинного целого из локальной переменной iload_0 = 26; //Загрузка целого из локальной переменной 0 iload_1 = 27; //Загрузка целого из локальной переменной 1 iload_2 = 28; //Загрузка целого из локальной переменной 2 iload_3 = 29; //Загрузка целого из локальной переменной 3 lload_0 = 30; //Загрузка длинного целого из локальной переменной 0 lload_1 = 31; //Загрузка длинного целого из локальной переменной 1 lload_2 = 32; //Загрузка длинного целого из локальной переменной 2 lload_3 = 33; //Загрузка длинного целого из локальной переменной 3 fload = 23; //1,Загрузка вещественного одинарной точности из локальной переменной fload_0 = 34; //Загрузка вещественного одинарной точности из локальной переменной 0 fload_1 = 35; //Загрузка вещественного одинарной точности из локальной переменной 1 fload_2 = 36; //Загрузка вещественного одинарной точности из локальной переменной 2 fload_3 = 37; //Загрузка вещественного одинарной точности из локальной переменной 3 dload = 24; //1,Загрузка вещественного двойной точности из локальной переменной dload_0 = 38; //Загрузка вещественного двойной точности из локальной переменной 0 dload_1 = 39; //Загрузка вещественного двойной точности из локальной переменной 1 dload_2 = 40; //Загрузка вещественного двойной точности из локальной переменной 2 dload_3 = 41; //Загрузка вещественного двойной точности из локальной переменной 3 aload = 25; //1,Загрузка объектной ссылки из локальной переменной aload_0 = 42; //Загрузка объектной ссылки из локальной переменной 0 aload_1 = 43; //Загрузка объектной ссылки из локальной переменной 1 aload_2 = 44; //Загрузка объектной ссылки из локальной переменной 2 aload_3 = 45; //Загрузка объектной ссылки из локальной переменной 3 istore = 54; //1,Сохранение целого значения в локальной переменной istore_0 = 59; //Сохранение целого в локальной переменной 0 istore_1 = 60; //Сохранение целого в локальной переменной 1 istore_2 = 61; //Сохранение целого в локальной переменной 2 istore_3 = 62; //Сохранение целого в локальной переменной 3 lstore = 55; //1,Сохранение длинного целого в локальной переменной lstore_0 = 63; //Сохранение длинного целого в локальной переменной 0 lstore_1 = 64; //Сохранение длинного целого в локальной переменной 1 lstore_2 = 65; //Сохранение длинного целого в локальной переменной 2 lstore_3 = 66; //Сохранение длинного целого в локальной переменной 3 fstore = 56; //1,Сохранение вещественного одинарной точности в локальной переменной fstore_0 = 67; //Сохранение вещественного одинарной точности в локальной переменной 0 fstore_1 = 68; //Сохранение вещественного одинарной точности в локальной переменной 1 fstore_2 = 69; //Сохранение вещественного одинарной точности в локальной переменной 2 fstore_3 = 70; //Сохранение вещественного одинарной точности в локальной переменной 3 dstore = 57; //1,Сохранение двойного вещественного в локальной переменной dstore_0 = 71; //Сохранение двойного вещественного в локальной переменной 0 dstore_1 = 72; //Сохранение двойного вещественного в локальной переменной 1 dstore_2 = 73; //Сохранение двойного вещественного в локальной переменной 2 dstore_3 = 74; //Сохранение двойного вещественного в локальной переменной 3 astore = 58; //1,Сохранение объектной ссылки в локальной переменной astore_0 = 75; //Сохранение объектной ссылки в локальной переменной 0 astore_1 = 76; //Сохранение объектной ссылки в локальной переменной 1 astore_2 = 77; //Сохранение объектной ссылки в локальной переменной 2 astore_3 = 78; //Сохранение объектной ссылки в локальной переменной 3 iinc = 132; //2,Увеличение локальной переменной на константу wide = 196; //1,Расширенный индекс для доступа к локальным переменным для команд загрузки, сохранения и приращения newarray = 188; //atype> T_BOOLEAN=4,T_CHAR=5,T_FLOAT=6,T_DOUBLE=7,T_BYTE=8 ,T_SHORT=9,T_INT=9,T_LONG=11 anewarray = 189; //2,Объявление нового массива из ссылок на объекты multianewarray = 197; //2,Размещение нового многомерного массива arraylength = 190; //Возвращает длину массива iaload = 46; //Загрузка целого из массива laload = 47; //Загрузка длинного целого из массива faload = 48; //Загрузка вещественного из массива daload = 49; //Загрузка двойного вещественного из массива aaload = 50; //Загрузка объектной ссылки из массива baload = 51; //Загрузка байта со знаком из массива caload = 52; //Загрузка символа из массива saload = 53; //Загрузка короткого из массива iastore = 79; //Сохранение в целочисленном массиве lastore = 80; //Сохранение в массиве из длинных целых fastore = 81; //Сохранение в массиве из одинарных вещественных dastore = 82; //Сохранение в массиве из двойных вещественных aastore = 83; //Сохранение в массиве из объектных ссылок bastore = 84; //Сохранение в массиве байтов со знаком castore = 85; //Сохранение в символьном массиве sastore = 86; //Сохранение в массиве из коротких целых nop = 0; //Ничего не делает pop = 87; //Извлечение слова с вершины стека pop2 = 88; //Извлечение двух слов с вершины стека dup = 89; //Дублирование слова на вершине стека dup2 = 92; //Дублирование двух слов на вершине стека dup_x1 = 90; //Дублирование слово на вершине стека и помещение копии в стек на два слова ниже dup2_x1 = 93; //Дублирование двух слов на вершине стека и помещение копий на два слова ниже dup_x2 = 91; //Дублирование вершины стека и помещение копии на три слова ниже dup2_x2 = 94; //Дублирование двух слов на вершине стека и помещение копий на три слова ниже swap = 95; //Обмен двух слов на вершине стека iadd = 96; //Сложение целых ladd = 97; //Сложение длинных целых fadd = 98; //Сложение одинарных вещественных dadd = 99; //Сложение двойных вещественных isub = 100; //Вычитание целых lsub = 101; //Вычитание длинных целых fsub = 102; //Вычитание одинарных вещественных dsub = 103; //Вычитание двойных вещественных imul = 104; //Умножение целых lmul = 105; //Умножение длинных целых fmul = 106; //Умножение одинарных вещественных dmul = 107; //Умножение двойных вещественных idiv = 108; //Деление целых ldiv = 109; //Деление длинных целых fdiv = 110; //Деление одинарных вещественных ddiv = 111; //Деление двойных вещественных irem = 112; //Остаток от деления целых lrem = 113; //Остаток от деления длинных целых frem = 114; //Остаток от деления одинарных вещественных drem = 115; //Остаток от деления двойных вещественных ineg = 116; //Отрицание целого leg = 117; //Отрицание длинного целого fneg = 118; //Отрицание одинарного вещественного dneg = 119; //Отрицание двойного вещественного числа ishl = 120; //Сдвиг целого влево ishr = 122; //Арифметический сдвиг целого вправо iushr = 124; //Логический сдвиг целого вправо lshl = 121; //Сдвиг длинного целого влево lshr = 123; //Арифметический сдвиг длинного целого вправо lushr = 125; //Логический сдвиг длинного целого вправо iand = 126; //Логическое И с операндами целого типа land = 127; //Логическое И с операндами длинного целого типа ior = 128; //Логическое ИЛИ с целочисленными операндами lor = 129; //Логическое ИЛИ с операндами длинного целого типа ixor = 130; //Исключающее ИЛИ с целочисленными операндами lxor = 131; //Исключающее ИЛИ с операндами длинного целого типа i2l = 133; //Преобразование целого в длинное целое i2f = 134; //Целое в вещественное i2d = 135; //Целое в двойное вещественное l2i = 136; //Длинное целое в целое l2f = 137; //Длинное целое в вещественное l2d = 138; //Длинное целое в двойное вещественное f2i = 139; //Вещественное в целое f2l = 140; //Вещественное в длинное целое f2d = 141; //Вещественное в двойное вещественное d2i = 142; //Двойное вещественное в целое d2l = 143; //Двойное вещественное в длинное целое d2f = 144; //Двойное вещественное в вещественное int2byte = 145; //Целое в знаковый байт int2char = 146; //Целое в символ int2short = 147; //Целое в короткое ifeq = 153; //2,Переход, если равно 0 ifnull = 198; //2,Переход, если пустой указатель iflt = 155; //2,Переход, если меньше 0 ifle = 158; //2,Переход, если меньше или равно 0 ifne = 154; //2,Переход, если не равно 0 ifnonnull = 199; //2,Переход, если не пустой указатель ifgt = 157; //2,Переход, если больше 0 ifge = 156; //2,Переход, если больше или равно 0 if_icmpeq = 159; //2,Переход, если целые равны if_icmpne = 160; //2,Переход, если целые не равны if_icmplt = 161; //2,Переход, если целое меньше 0 if_icmpgt = 163; //2,Переход, если целое больше 0 if_icmple = 164; //2,Переход, если целое меньше или равно if_icmpge = 162; //2,Переход, если целое больше или равно lcmp = 148; //Сравнение длинных целых fcmpl = 149; //Сравнение вещественных одинарной точности (-1 при NaN) fcmpg = 150; //Сравнение вещественных одинарной точности (1 при NaN) dcmpl = 151; //Сравнение вещественных двойной точности(-1 при NaN) dcmpg = 152; //Сравнение вещественных двойной точности(1 при NaN) if_acmpeq = 165; //2,Переход, если ссылки на объект равны if_acmpne = 166; //2,Переход, если ссылки на объект не равны goto = 167; //2,Переход на goto_w = 200; //4,Переход на (расширенный индекс) jsr = 168; //2,Переход на подпрограмму jsr_w = 201; //4,Переход на подпрограмму (расширенный индекс) ret = 169; //1,Возврат из подпрограммы ret_w = 209; //2,Возврат из подпрограммы (расширенный индекс) ireturn = 172; //Возврат целого значения функции lreturn = 173; //Возврат длинного целого значения функции freturn = 174; //Возврат одинарного вещественного значения функции dreturn = 175; //Возврат двойного вещественного значения функции areturn = 176; //Возврат объектной ссылки из функции return = 177; //Возврат(опустошающий) из процедуры breakpoint = 202; //Остановка и передача контроля обработчику прерываний tableswitch = 170; //Доступ к таблице перехода по индексу и переход lookupswitch = 171; //Доступ к таблице перехода по сравнению с ключом и переход putfield = 181; //2,Установка поля в объекте getfield = 180; //2,Перенос поля из объекта putstatic = 179; //2,Установка статического поля в классе getstatic = 178; //2,Получение статического поля класса invokevirtual = 182; //2,Вызывает метод экземпляра, основываясь на типе времени выполнения invokenonvirtual = 183; //2,Вызывает метод экземпляра, основываясь на не виртуальном типе invokestatic = 184; //2,Вызов метода класса (статического метода) invokeinterface = 185; //4,Вызывает метод интерфейса athrow = 191; //Генерация обработки или ошибки new = 187; //2,Создает новый объект checkcast = 192; //2,Проверяет, что объект имеет данный тип instanceof = 193; //2,Определяет, имеет ли объект данный тип monitorenter = 194; //Вход в контролируемую область кода monitorexit = 195; //Выход из контролируемой области кода |
Re: создание MIDletPascal compiler'a
Ну ты монстрище... Мля, зачот, не знаю прада как тут плюсы ставить, да и хрен с ними... Потом обставимся...
Такис, ча займусь токда переводом примера верхнего на нормальный язык. А насчот массивов - то да, структуры можн писать write() но медленно работает, токда как BlockWrite() и массивы помойму в 10 000 раз быстрее, тем боле что сам dcc32.exe на С++ написан, а все что написано на Си по определению луче на массивы перевести. Здорово оно с ними работает. Кста можно извратица в Delphi и сделать чота типа типизированых массивов, шоб голову не ломать с типами данных, определить тип вроде _head,_cpool... а потом просто обращатся к ним напрямую, Header[_head][$0] = $CA извратица б ишо как нить так Header[_head][0..3] := ([$0,$1,$2,$3]); Ну да ето просто вопрос техники... |
Re: создание MIDletPascal compiler'a
Вкуриваем устройство JAVA компилятора!
Итак возьмем наш стандартный файл HelloWord.java и скомпилим его для разбора на косточки. class HelloWorld{ public static void main(String [] args){ System.out.println("Hello World!"); } } Вот что получается при просмотре в каком нибудь HEXeditor: CA FE BA BE ------------------------------------ Кюєѕ 00 00 ------------------------------------------ .. 00 30 ------------------------------------------ .0 00 1D ------------------------------------------ .. 01 00 0A --------------------------------------- ... 48 65 6C 6C 6F 57 6F 72 6C 64 ------------------ HelloWorld 07 00 01 --------------------------------------- ... 01 00 10 --------------------------------------- ... 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 -java/lang/Object 07 00 03 --------------------------------------- ... 01 00 04 --------------------------------------- ... 6D 61 69 6E ------------------------------------ main 01 00 16 --------------------------------------- ... 28 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 ------------------------------ ([Ljava/lang/String.)V 01 00 04 --------------------------------------- ... 43 6F 64 65 ------------------------------------ Code 01 00 0F --------------------------------------- ... 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 --- LineNumberTable 01 00 03 --------------------------------------- ... 6F 75 74 --------------------------------------- out 01 00 15 --------------------------------------- ... 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 ------ Ljava/io/Print 53 74 72 65 61 6D 3B --------------------------- Stream; 0C 00 09 00 0A 01 00 10 ------------------------ ........ 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 20 java/lang/System .................................................. 07 00 0C 09 00 0D 00 0B 01 00 0C 48 65 6C 6C 6F ...........Hello 57 6F 72 6C 64 21 08 00 0F 01 00 07 70 72 69 6E World!......prin 74 6C 6E 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E tln...(Ljava/lan 67 2F 53 74 72 69 6E 67 3B 29 56 0C 00 11 00 12 g/String)V..... 01 00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 ...java/io/Print 53 74 72 65 61 6D 07 00 14 0A 00 15 00 13 01 00 Stream.......... 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 0C 00 17 .<init>...()V... 00 18 0A 00 04 00 19 01 00 0A 53 6F 75 72 63 65 ..........Source 46 69 6C 65 01 00 0F 48 65 6C 6C 6F 57 6F 72 6C File...HelloWorl 64 2E 6A 61 76 61 00 20 d.java. .................................................. 00 02 00 04 00 00 00 00 ........ 00 02 00 09 00 05 00 06 00 01 00 07 00 00 00 25 ...............% 00 02 00 01 00 00 00 09 B2 00 0E 12 10 B6 00 16 ........І....¶.. B1 00 00 00 01 00 08 00 00 00 0A 00 02 00 00 00 ±............... 03 00 08 00 04 00 00 00 17 00 18 00 01 00 07 00 ................ 00 00 21 00 01 00 01 00 00 00 05 2A B7 00 1A B1 ..!........*·..± 00 00 00 01 00 08 00 00 00 0A 00 02 00 00 00 01 ................ 00 04 00 01 00 01 00 1B 00 00 00 02 00 1C .............. Я разделил на секции, что бы было понятнее. Поехали. Сигнатура CLASS файла. CA FE BA BE Кюєѕ Далее идет описание младшей и старшей версии компилятора 00 00 .. // Младшая 0.0 00 30 .0 // Старшая 3.0 Число объектов в описании файла 00 1D .. Тоесть число всех наших записей в пуле HelloWorld java/lang/Object main ([Ljava/lang/String)V Code LineNumberTable Тут равно 29... нужно проверить на меньшее значение!? Самое интересное начинается. Описание или КОНСТАНТНЫЙ ПУЛ По таблице смотрим 1 байт или tag, он равен 01 или в переводе CONSTANT_Utf8, тобиш значит в описании будет срока UTF8, следующие два поля 00 0А говорят нам о количестве элементов пула, то есть по просту размер строки который тут равен 10 или 0А в 16h 01 00 0A ... Потом идет сама строка 48 65 6C 6C 6F 57 6F 72 6C 64 HelloWorld Сдесь я ещё не совсем вкурил но по всему, что это CONSTANT_Class 07 00 01 Далее опять описание CONSTANT_Utf8 строки и размер 01 00 10 ... 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 java/lang/Object И так далее и тому подобное...Тоесть проще не куда, вот поэтому наверно декомпилировать классы очень легко, но тут возникает проблемка, компилятор придется делать в купе с транслятором PASCAL->JAVA, а затем уже компилировать, можно в принципе и сразу, но писать придется на чистом ООП... |
Re: создание MIDletPascal compiler'a
Все братва, разобрался...
Все просто, как и все простое... Гы... Значит давайте пройдем маленький цикл компиляции в ручную, что бы понять смысл байт-кода. class HelloWorld{ public static void main(String [] args){ System.out.println("Hello World!"); } } Вообщем, весь процесс сводится к записи двумерного массива примерно так, читаем сверху в низ class HelloWorld HelloWorld– это строка, значит тип UTF8 Array[1][0..0A]=” HelloWorld” 48 65 6C 6C 6F 57 6F 72 6C 64 Это класс, значит просто указываем на имя класса Array[2][0..03]=” 01”[0001]->HelloWorld07 00 01 Вызываем стандартные библиотеки Java Array[3][0..10]=”java/lang/Object” ....... И т.д, тоесть нам надо описать тип новый массива и писать в него 4 поля которые нам нужны, мы всегда знаем, это индекс массива, его длину, его содержимое и его тип, потом этот массив считываем в файл и добавляем асм код стандартных функций Java... А теперь шо я хотел написать на форуме МП. Код:
Здаров гандоны и пиндосы! |
Ответ: создание MIDletPascal compiler'a
Поддерживаю. С интересом наблюдаю за развитием проекта...
|
Ответ: создание MIDletPascal compiler'a
Это я такой тупой, что ничего не понимаю, или просто из-за того, что только проснулся? О_о
|
Ответ: создание MIDletPascal compiler'a
Вложений: 1
вложенный файл <1.zip> - кусочек из "Canterbury Pascal for J2ME" (компилятора написанного на java).
файл pascal/pas3/mhc/compiler/ClassFile.* дает структуру и некоторые алгоритмы записи. Анализировать классы буду когда полностью спроектирую удобную структуру представления в delphi, т.е. когда корректно будут загружаться хотябы простейшие class-файлы. кто хочет поучавствовать в проекте вот декомпилер calss-файлов: Java Code Viewer 6.0. -keyGen внутри архива (конвертирует из *.class в *.java) ссылка на скачивание http://www.samsfan.ru/soft/?action=get&openwin=1&id=49 ссылка на страничку http://www.samsfan.ru/soft/?action=view&id=49&parent=7 если есть дельные советы прошу выкладывать кусочки кода, или ссылки для скачки исходников java-виртуальных_машин/ассемблеров/дизассемблеров/и т.д. но в пределах разумного, я каждый байт в инете считаю... p.s. Давайте не будем ругаться,... потому что: 1. пользуемся чей-то выложенной в инете информацией 2. какой-бы не был MP, на нем другие работают 3. на данный момент у нас нет хоть какого-либо компилятора |
Ответ: создание MIDletPascal compiler'a
Однако, свежо! Интересная веточка, желаю вам удачи в создании русского MP.
|
Ответ: создание MIDletPascal compiler'a
лутче бы написали бы компилятор из какого нибудь более универсального синтаксиса и два транслятора из pascal-подобного и basic-подобного синтаксиса
правда в прочем можно транслировать на java и компилить уже обычным способом |
Re: создание MIDletPascal compiler'a
Ребят, да вы не понимаете... Ето пока наброски, потом, когда перейдем к синтаксическому анализатору каждый сможет свой язык прикрутить, вплоть до выдуманого. Просто я сейчас иду методом рекурсивного подъёма, а не как в классической книге дракона метод рекурсивного спуска. Почему? Да потому что виден сразу результат работы, во вторых можно проверять на ходу работоспособность и в третьих, когда подходишь уже к оформлению языка (на каком будет проходить в принципе программирование) у тебя уже все готово, то есть остаётся лишь придумать или взять какой нить язык за основу и вписать его в лекс. анализ...
Просто сейчас я пытаюсь объяснить структуру БАЙТ-КОДА который будет на выходе, попросту CLASS файл, затем у нас пойдут простейшие функции, которые переводят строки в этот самый байт код... Но, по структуре CLASS файла можно понять, что он состоит из нескольких секций и в основном самая большая из них - это Заголовок файла. Потом лексический анализатор пробежится по строчкам кода (причом пробежиться он по правилам заданным нами) и если не встретит ошибки отдаст строку на растерзание синтаксическому анализатору... Вот в кратце как работает эта связка на примере строки class HelloWorld{ Пусть у нас будет L– лексический анализатор а S– синтаксический L – встретил “class” отдает S-> “class” S – возвращает L<-_CLASSES то есть “class” у нас структура Ошибки нет, записываем в массив с номером N+1 07 00 {номер N} L – далее должно быть название строка UTF8 L – следующийтокен “HelloWorld” отдает S->“HelloWorld” S – возвращает L<-_UTF8 то есть строка Lсверяет UTF8 == _UTF8 ошибки нет Записываем в массив с номером Nпоследовательность байт строки “HelloWorld” или 48 65 6C 6C 6F 57 6F 72 6C 64 И так в цикле и рекурсивно... Тоесть у нас одна рекурсивная функция будет отдавать три варианта 1.Ошибки нет правила совпадают 2.Ошибки нет правила не совпадают 3.Ошибка В первом случае все нормально и пишется код, в третьем выводится ошибка а во втором управление передается точно такой же рекурсивной функции, которая разберёт уже другую строку, например выражение, и т.д... |
Re: создание MIDletPascal compiler'a
Итак мы подошли к созданию функций нижнего уровня! Почему я так заострил вопрос о именно нижнем уровне? Все очень просто. Многие простые компиляторы и интерпритаторы начинаются с верхнего уровня, и когда доходят до создания файлов то происходит как бы ломка кода... Или приходится дорабатывать анализаторы, что бы код был по возможности оптимальным, или дорабатывать выходной файл (ASMили байт-код)... В любом случае ошибки допущенные сверху сказываются на коде в прогрессии.
Итак предлагаю определить две переменные. Первая это Var Token : array of record Name : String; Types : Byte; Code : Array of byte; end; ByteCode: array of record Name : String; Types : Byte; Len : Byte; end; Теперь представте как работает Лексич. Анализатор. Он разобьет наш скрипт на отдельные лексемы, но не просто а запишет их в переменную Token? Поэтому строка вида class HelloWorld{ превратится в набор Token[0].Name = “Class” Token[0].Types = _CLASSES Token[0].Code[] = [] Token[1].Name = “ HelloWorld” Token[1].Types = _UTF8 Token[1].Code[] = [$48, $65, $6C, $6C, $6F, $57, $6F, $72, $6C, $64] Token[2].Name = “{” Token[2].Types = _OPERATOR Token[2].Code[] = [] Что это даст? Все просто, при синтаксическом анализе мы сразу будем лепить код без хитрых манипуляций и во вторых сразу же можно будет формировать байт-код заголовка на основании предыдущего и последующего кода... Ну ладно, щас попробую занятся уже формированием CLASS файла... |
Ответ: создание MIDletPascal compiler'a
вот сбрал приблизительную модель загрузки clsass-файлов, но после считывания константного пула, где-то рвет в размерах считываемых байтов, соответственно неверно заполняются поля размера ниже-следующих структур, посмотрите кто-нить в чем здесь неправ.
формат и доку брал из предоставленной информации. Программу можно компилировать как и в TurboPascal 7.0, так и Delphi 7.0 только после создания .exe-файла в Delphi антивирус кричит на него что это вирус... Код:
{$R+,S+} |
Re: создание MIDletPascal compiler'a
Ну вот мля куды ты гонишь? У меня падает компилер на этом
reset(f,1); <- Вот тута... Но ладно, ща буду разбирацо! Сори файл fw.cla на русском создал... Пойду просыпацоо ... for i:=0 to cf.methods_count-1 do begin writeln(hexw(rc),'hmethod_info:',i:3,'---------'); method_info; // <- Тут зацикливается end; ----------------------------------------------------------------- А ваще красавец! 100 балов! Ты тока шо создал Дизассемблер Java, если синтаксис немного поменять, JavaBite копия! Гы...ы.ы.ыыыыы..... Ты токма не гони лошадей... Ща буим смореть... Ток не пойму чо у тя антивирь кричит? У меня лицуха... все ОК... KIS7 |
Ответ: создание MIDletPascal compiler'a
хм, сейчас глянул, а некоторые символы исчезли в исходнике...
наверное при конвертировке почему-то потерялись.. function swap2(pointer; offs:integer) : pointer; должно быть function swap2(P : pointer; offs:integer) : pointer; тоже самое с function swap4(... |
Ответ: создание MIDletPascal compiler'a
да и еще в строке: pGenericAttribute_info:=swap2(swap2{4}(p,0),0);
поставить pGenericAttribute_info:=swap2(swap4(p,0),0); тестировал, забыл убрать, думал описка там тип 4 байта, я ставил 2.. ПРИМЕЧАНИЕ: компилятор нужно настроить чтобы он не выравнивал переменные в памяти, а то размер структур будет больше, т.е. sizeof(...) и д.р. будет работать некорректно |
Ответ: создание MIDletPascal compiler'a
Цитата:
Код:
const |
Ответ: создание MIDletPascal compiler'a
вот передалел немножко на свежую голову... - заработало,
теперь нужно сделать чтоб распознавались блоки "Code", "Exception", "LocalVariableTable" будет свободное время - надо начинать делать java-ассемблер {$apptype console} {$R+,S+} const CONSTANT_Class = 7; CONSTANT_Fieldref = 9; CONSTANT_Methodref = 10; CONSTANT_InterfaceMethodref = 11; CONSTANT_String = 8; CONSTANT_Integer = 3; CONSTANT_Float = 4; CONSTANT_Long = 5; CONSTANT_Double = 6; CONSTANT_NameAndType = 12; CONSTANT_Utf8 = 1; CONSTANT_Unicode = 2; {------------------------------} ACC_PUBLIC = 1; ACC_PRIVATE = 2; ACC_PROTECTED = 4; ACC_STATIC = 8; ACC_FINAL = 16; ACC_SYNCHRONIZED = 32; ACC_SUPER = 32; ACC_VOLATILE = 64; ACC_TRANSIENT = 128; ACC_NATIVE = 256; ACC_INTERFACE = 512; ACC_ABSTRACT = 1024; {} type tfield_info = record access_flags : word; name_index : word; signature_index : word; attributes_count : word; {attributes[attribute_count]} end; {} tmethod_info = record access_flags : word; name_index : word; signature_index : word; attributes_count : word; {attributes[attribute_count]} end; {--атрибуты--} tGenericAttribute_info = record attribute_name : word; attribute_length : longInt; {info[attribute_length] of byte} end; {} tSourceFile_attribute = record attribute_name_index : word; attribute_length : longInt; sourcefile_index : word; end; {} tLineNumberTable_attribute = record attribute_name_index : word; attribute_length : longInt; line_number_table_length : word; {line_number_table[line_number_table_length] of record start_pc,line_number:word;end;} end; {} tConstantValue_attribute = record attribute_name_index : word; attribute_length : longInt; constantvalue_index : word; end; {} tLocalVariableTable_attribute = record attribute_name_index : word; attribute_length : longInt; local_variable_table_length : word; {local_variable_table[local_variable_table_length]} end; tLocal_variable_table = record start_pc : word; length : word; name_index : word; signature_index : word; slot : word; end; {} tExceptions_attribute = record attribute_name_index : word; attribute_length : longInt; number_of_exceptions : word; {exception_index_table[number_of_exceptions] of word} end; {} tInnerClasses_attribute = record attribute_name_index : word; attribute_length : longInt; number_of_classes : word; {classes[number_of_classes] of record inner_class_info_index : word; outer_class_info_index : word; inner_name_index : word; inner_class_access_flags : word; end} end; {} tSynthetic_attribute = record attribute_name_index : word; attribute_length : longInt; end; {} Deprecated_attribute = record attribute_name_index : word; attribute_length : longInt; end; {} tCode_attribute = record attribute_name_index : word; attribute_length : longInt; max_stack : word; max_locals : word; code_length : longInt; end; {code[code_length]} {exception_table_length : word;{***} {exception_table[exception_table_length]} {attributes_count : word;{***} {attribute_info[attribute_count]} tException_table = record start_pc : word; end_pc : word; handler_pc : word; catch_type : word; end; {--------------------------} tarr = array[0..$FFFF-1] of byte; var cf : record {ClassFile} magic : longInt; minor_version : word; major_version : word; constant_pool_count : word; cp_info :^tarr;{constant_pool[constant_pool_count - 1];} access_flags : word; this_class : word; super_class : word; interfaces_count : word; interfaces :^tarr;{[interfaces_count];} fields_count : word; field_info :^tarr;{fields[fields_count];} methods_count : word; method_info :^tarr;{methods[methods_count];} attributes_count : word; attribute_info :^tarr;{attributes[attribute_count];} end; var f : file; i,j,n,rc : integer; {longInt;} s : string; tag : byte; p :^byte; pfield_info :^tfield_info; pmethod_info :^tmethod_info; pGenericAttribute_info :^tGenericAttribute_info; pCode_attribute :^tCode_attribute; pException_table :^tException_table; pexception_table_length :^word; pattributes_count :^word; pLocalVariableTable_attribute :^tLocalVariableTable_attribute; pLocal_variable_table :^tLocal_variable_table; function hex(b : byte) : string; const h : array[0..$F] of char = '0123456789ABCDEF'; begin hex := h[b shr 4]+h[b and $F]; end; function hexw(w : word) : string; begin hexw := hex(hi(w))+hex(lo(w)); end; function get(p : pointer; count : integer) : pointer; var n : integer; begin blockRead(f,p^,count,n); inc(longInt(p),n); {pasc} inc(rc,n); get := p; {get := ptr(cardinal(p)+count); //delphi} end; function swap2(p : pointer; offs : integer) : pointer; var b1,b2 :^byte; b : byte; begin dec(longInt(p),offs+1); b1 := p; dec(longInt(p)); b2 := p; b := b1^; b1^ := b2^; b2^ := b; swap2 := p; end; function swap4(p : pointer; offs : integer) : pointer; var w1,w2 : ^word; w : word; begin w1 := swap2(p,0); w2 := swap2(w1,0); w := w1^; w1^ := w2^; w2^ := w; swap4 := w2; end; function pconst(i : integer) : pointer; var w :^word; p :^byte; begin p := nil; if (i>=1) and (i<cf.constant_pool_count-1) then begin p := @cf.cp_info^; while i>=1 do begin case p^ of CONSTANT_Class: inc(p,1+2); CONSTANT_Fieldref,CONSTANT_Methodref,CONSTANT_Inte rfaceMethodref: inc(p,1+4); CONSTANT_String: inc(p,1+2); CONSTANT_Integer,CONSTANT_Float: inc(p,1+4); CONSTANT_Long: inc(p,1+8 ); CONSTANT_NameAndType: inc(p,1+4); CONSTANT_Utf8, CONSTANT_Unicode: begin {null=$0000, 1b=$0001-$007F,2b=$0008-$07FF,3b=$0800-$FFFF{} inc(p); w := @p^; inc(p,2); inc(p,w^) end; else begin p := nil; i := 0; end; end; dec(i); end; end; pconst := p; end; function getConstStr(index : word) : string; var s : string; i,j : word; p :^byte; w :^word; begin s := ''; p := pconst(index); if p<>nil then case p^ of CONSTANT_Class: begin w := @p^; inc(w); p := pconst(w^); end; CONSTANT_Fieldref,CONSTANT_Methodref,CONSTANT_Inte rfaceMethodref: begin w := @p^; inc(w); p := pconst(w^); end; CONSTANT_String: begin w := @p^; inc(w); p := pconst(w^); end; CONSTANT_NameAndType: begin w := @p^; inc(w); p := pconst(w^); end; end; {null=$0000, 1b=$0001-$007F,2b=$0008-$07FF,3b=$0800-$FFFF{} if p<>nil then if (p^ in [CONSTANT_Utf8, CONSTANT_Unicode]) then begin inc(p); w := @p^; inc(p,2); for j := 0 to w^-1 do begin s := s+chr(p^); inc(p); end; end; getConstStr := s; end; {-------------------} procedure load_const; begin get(p,1); tag := p^; inc(p); write(tag:2,' '); case tag of CONSTANT_Class: begin p := get(p,2); write('CONSTANT_Class:',word(swap2(p,0)^)); end; CONSTANT_Fieldref,CONSTANT_Methodref,CONSTANT_Inte rfaceMethodref: begin case tag of CONSTANT_Fieldref: write('CONSTANT_Fieldref:'); CONSTANT_Methodref: write('CONSTANT_Methodref:'); CONSTANT_InterfaceMethodref: write('CONSTANT_InterfaceMethodref:'); end; p := get(p,4); write(word(swap2(p,2)^),' ',word(swap2(p,0)^)); end; CONSTANT_String: begin p := get(p,2); write('CONSTANT_String:',word(swap2(p,0)^)); end; CONSTANT_Integer,CONSTANT_Float: begin case tag of CONSTANT_Integer: write('CONSTANT_Integer:'); CONSTANT_Float: write('CONSTANT_Float:'); end; p := get(p,4); write(longInt(swap4(p,0)^)); end; CONSTANT_Long,CONSTANT_Double: begin case tag of CONSTANT_Long: write('CONSTANT_Integer:'); CONSTANT_Double: write('CONSTANT_Double:'); end; p := get(p,8 ); write('_hi_',longInt(swap4(p,4)^),'_lo_',longInt(s wap4(p,0)^)); end; CONSTANT_NameAndType: begin p := get(p,4); write('CONSTANT_NameAndType:',word(swap2(p,2)^),' ',word(swap2(p,0)^)); end; CONSTANT_Utf8, CONSTANT_Unicode: begin {null=$0000, 1b=$0001-$007F,2b=$0008-$07FF,3b=$0800-$FFFF{} p := get(p,2); {length} n := word(swap2(p,0)^); write('CONSTANT_Utf8-Unicode [',n,']='); for j := 0 to n-1 do begin get(p,1); write(chr(p^)); inc(p); end; end; else if tag<>0 then begin write('error:',tag); halt; end; end; writeln; end; procedure load_attribute_info; begin writeln(hexw(rc), 'h GenericAttribute_info'); p:=get(p,sizeof(pGenericAttribute_info^)); pGenericAttribute_info:=swap2(swap4(p,0),0); writeln('attribute_name:',pGenericAttribute_info^. attribute_name); writeln('attribute_length:',pGenericAttribute_info ^.attribute_length); s := getConstStr(pGenericAttribute_info^.attribute_name ); if s='Code' then begin writeln(hexw(rc), 'h Code'); p := get(p,sizeof(pCode_attribute^)); pCode_attribute := swap2(swap4(swap2(swap2(swap4(p,0),0),0),0),0); writeln(hexw(rc-sizeof(pCode_attribute^.attribute_name_index)), ' attribute_name_index:',pCode_attribute^.attribute_ name_index); writeln(hexw(rc-sizeof(pCode_attribute^.attribute_length)), ' attribute_length:',pCode_attribute^.attribute_leng th); writeln(hexw(rc-sizeof(pCode_attribute^.max_stack)), ' max_stack:',pCode_attribute^.max_stack); writeln(hexw(rc-sizeof(pCode_attribute^.max_locals)), ' max_locals:',pCode_attribute^.max_locals); writeln(hexw(rc-sizeof(pCode_attribute^.code_length)), ' code_length:',pCode_attribute^.code_length); for n := 0 to pCode_attribute^.code_length-1 do p:=get(p,1); p := get(p,sizeof(pexception_table_length^)); pexception_table_length:=swap2(p,0); for n := 0 to pexception_table_length^-1 do begin p := get(p,sizeof(pException_table^)); pException_table := swap2(swap2(swap2(swap2(p,0),0),0),0); end; p := get(p,sizeof(pattributes_count^)); pattributes_count :=swap2(p,0); for n := 0 to pattributes_count^-1 do load_attribute_info; end else if s='LocalVariableTable' then begin writeln(hexw(rc), 'h LocalVariableTable'); p := get(p,sizeof(pLocalVariableTable_attribute^)); pLocalVariableTable_attribute := swap2(swap4(swap2(p,0),0),0); writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.attribute_na me_index)), ' attribute_name_index:',pLocalVariableTable_attribu te^.attribute_name_index); writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.attribute_le ngth)), ' attribute_length:',pLocalVariableTable_attribute^. attribute_length); writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.local_variab le_table_length)), ' local_variable_table_length:',pLocalVariableTable_ attribute^.local_variable_table_length); for n := 0 to pLocalVariableTable_attribute^.local_variable_tabl e_length-1 do begin p := get(p,sizeof(pLocal_variable_table^)); pLocal_variable_table := swap2(swap2(swap2(swap2(swap2(p,0),0),0),0),0); writeln('start_pc:',pLocal_variable_table^.start_p c); writeln('length:',pLocal_variable_table^.length); writeln('name_index:',pLocal_variable_table^.name_ index); writeln('signature_index:',pLocal_variable_table^. signature_index); writeln('slot:',pLocal_variable_table^.slot); end; end {if s='SourceFile' then begin end else if s='LineNumberTable' then begin end{} else {don't know... skip atributes} begin for n := 0 to pGenericAttribute_info^.attribute_length-1 do begin get(p,1); write(hex(byte(p^)),' '); inc(p); end; end; writeln; end; procedure load_interfaces; begin p := get(p,2); write(word(swap2(p,0)^),','); end; procedure load_field_info; begin p := get(p,sizeof(pfield_info^)); pfield_info := swap2(swap2(swap2(swap2(p,0),0),0),0); writeln('access_flags:',pfield_info^.access_flags) ; writeln('name_index:',pfield_info^.name_index); writeln('signature_index:',pfield_info^.signature_ index); writeln('attributes_count:',pfield_info^.attribute s_count, ' offs:[',hexw(rc), 'h]'); for j := 0 to pfield_info^.attributes_count-1 do load_attribute_info; end; procedure method_info; begin p := get(p,sizeof(pmethod_info^)); pmethod_info := swap2(swap2(swap2(swap2(p,0),0),0),0); writeln('access_flags:',pmethod_info^.access_flags ); writeln('name_index:',pmethod_info^.name_index); writeln('signature_index:',pmethod_info^.signature _index); writeln('attributes_count:',pmethod_info^.attribut es_count, ' offs:[',hexw(rc), 'h]' ); for j := 0 to pmethod_info^.attributes_count-1 do load_attribute_info; end; begin getMem(cf.cp_info,$FFFF); getMem(cf.interfaces,$7FFF); getMem(cf.field_info,$FFFF); getMem(cf.method_info,$FFFF); getMem(cf.attribute_info,$FFFF); fillChar(cf.cp_info^, $FFFF, 0); fillChar(cf.interfaces^, $7FFF, 0); fillChar(cf.field_info^, $FFFF, 0); fillChar(cf.method_info^, $FFFF, 0); fillChar(cf.attribute_info^, $FFFF, 0); assign(f,'fw.cla'); {cf.magic := $CAFEBABE; cf.minor_version := $0000; cf.major_version := $002E; rewrite(f,1); blockWrite(f,cf.magic,sizeof(cf.magic),n); blockWrite(f,cf.minor_version,sizeof(cf.minor_vers ion),n); blockWrite(f,cf.major_version,sizeof(cf.major_vers ion),n);{...} reset(f,1); rc := 0; swap4(get(@cf.magic,sizeof(cf.magic)),0); swap2(get(@cf.minor_version,sizeof(cf.minor_versio n)),0); swap2(get(@cf.major_version,sizeof(cf.major_versio n)),0); swap2(get(@cf.constant_pool_count,sizeof(cf.consta nt_pool_count)),0); p := @cf.cp_info^; for i := 1 to cf.constant_pool_count-1 do {здесь именно с 1 по cf.constant_pool_count-1} begin write(hexw(rc-1),'h ',i:3,' '); load_const; {загрузка и распознование cp_info} end; writeln('__________________________'); swap2(get(@cf.access_flags,sizeof(cf.access_flags) ),0); writeln(hexw(rc-sizeof(cf.access_flags)),'h access_flags:',cf.access_flags); swap2(get(@cf.this_class,sizeof(cf.this_class)),0) ; writeln(hexw(rc-sizeof(cf.this_class)),'h this_class:',cf.this_class); swap2(get(@cf.super_class,sizeof(cf.super_class)), 0); writeln(hexw(rc-sizeof(cf.super_class)),'h super_class:',cf.super_class); writeln(#13#10'-----load_interfaces----'); swap2(get(@cf.interfaces_count,sizeof(cf.interface s_count)),0); writeln(hexw(rc-sizeof(cf.interfaces_count)),'h interfaces[',cf.interfaces_count,']='); p := @cf.interfaces^; for i := 0 to cf.interfaces_count-1 do load_interfaces; {загрузка interfaces} writeln(#13#10'__________________________'); writeln(#13#10'-----load_field_info----'); swap2(get(@cf.fields_count,sizeof(cf.fields_count) ),0); writeln(hexw(rc-sizeof(cf.fields_count)),'h field_info[',cf.fields_count,']='); p := @cf.field_info^; for i := 0 to cf.fields_count-1 do begin writeln(hexw(rc), 'h field_info:',i:3,'---------'); load_field_info; {загрузка field_info} end; writeln('__________________________'); writeln(#13#10'-----method_info----'); swap2(get(@cf.methods_count,sizeof(cf.methods_coun t)),0); writeln(hexw(rc-sizeof(cf.methods_count)), 'h method_info [',cf.methods_count,']='); p := @cf.method_info^; for i := 0 to cf.methods_count-1 do begin writeln(hexw(rc),'h method_info:',i:3,'---------'); method_info; {загрузка method_info} end; writeln('__________________________'); writeln('OFFSET:',hexw(rc)); swap2(get(@cf.attributes_count,sizeof(cf.attribute s_count)),0); writeln(hexw(rc-sizeof(cf.attributes_count)),'h attribute_info [',cf.attributes_count,']='); p := @cf.attribute_info^; for i := 0 to cf.attributes_count-1 do begin load_attribute_info; writeln('-'); end; close(f); freeMem(cf.attribute_info,$FFFF); freeMem(cf.method_info,$FFFF); freeMem(cf.field_info,$FFFF); freeMem(cf.interfaces,$7FFF); freeMem(cf.cp_info,$FFFF); end. |
Re: создание MIDletPascal compiler'a
а ты какой файл дизазмишь если не секрет? Я простой HelloWord, так у меня что тот, что этот зацикливается на методах а этот теперь еще и на атрибутах...
Мля... Сори, все ок... Я тож наверно от недосыпу тупить уж начал... |
Re: создание MIDletPascal compiler'a
Вобчем смотрим чо происходит
0009h 1 1 CONSTANT_Utf8-Unicode [10] = HelloWorld 0016h 2 7 CONSTANT_Class:1 0019h 3 1 CONSTANT_Utf8-Unicode [16] = java/lang/Object 002Ch 4 7 CONSTANT_Class:3 002Fh 5 1 CONSTANT_Utf8-Unicode [4] = main 0036h 6 1 CONSTANT_Utf8-Unicode [22] = ([Ljava/lang/String;)V 004Fh 7 1 CONSTANT_Utf8-Unicode [4] = Code 0056h 8 1 CONSTANT_Utf8-Unicode [15] = LineNumberTable 0068h 9 1 CONSTANT_Utf8-Unicode [3] = out 006Eh 10 1 CONSTANT_Utf8-Unicode [21] = Ljava/io/PrintStream; 0086h 11 12 CONSTANT_NameAndType: 9 10 008Bh 12 1 CONSTANT_Utf8-Unicode [16] = java/lang/System 009Eh 13 7 CONSTANT_Class: 12 00A1h 14 9 CONSTANT_Fieldref: 13 11 00A6h 15 1 CONSTANT_Utf8-Unicode [12] = Hello World! 00B5h 16 8 CONSTANT_String:15 00B8h 17 1 CONSTANT_Utf8-Unicode [7] = println 00C2h 18 1 CONSTANT_Utf8-Unicode [21] = (Ljava/lang/String;)V 00DAh 19 12 CONSTANT_NameAndType: 17 18 00DFh 20 1 CONSTANT_Utf8-Unicode [19] = java/io/PrintStream 00F5h 21 7 CONSTANT_Class: 20 00F8h 22 10 CONSTANT_Methodref: 21 19 00FDh 23 1 CONSTANT_Utf8-Unicode [6] = <init> 0106h 24 1 CONSTANT_Utf8-Unicode [3] = ()V 010Ch 25 12 CONSTANT_NameAndType: 23 24 0111h 26 10 CONSTANT_Methodref: 4 25 0116h 27 1 CONSTANT_Utf8-Unicode [10] = SourceFile 0123h 28 1 CONSTANT_Utf8-Unicode [15] = HelloWorld.java 0136h access_flags:32 0138h this_class:2 013Ah super_class:4 013Ch interfaces[0]= 013Eh field_info[0]= 0140h method_info [2]= 0142h method_info: 0--------- access_flags:9 name_index:5 signature_index:6 attributes_count:1 offs:[014Ah] 014Ah GenericAttribute_info attribute_name:7 <- Ссылкана 7 элемент “Code” attribute_length:37 <- Длинна 00 02 00 01 00 00 00 09 B2 00 0E 12 10 B6 00 16 B1 00 00 00 01 00 08 00 00 00 0A00 02 00 00 00 03 00 08 00 04 0175h method_info: 1--------- access_flags:0 name_index:23 signature_index:24 attributes_count:1 offs:[017Dh] 017Dh GenericAttribute_info attribute_name:7 <- Ссылкана 7 элемент “Code” attribute_length:33 <- Длинна 00 01 00 01 00 00 00 05 2A B7 00 1A B1 00 00 00 01 00 08 00 00 00 0A 00 02 00 00 00 01 00 04 00 01 OFFSET: 01A4 01A4h attribute_info [1]= красным выделил где данные уже считываюца, тоесть у нас уже атрибуты получены, поэтому дальше надо сразу разбирать код Вот на вскидку... procedure load_attribute_info; ... s := getConstStr(pGenericAttribute_info^.attribute_name - 1); // отнятьединицу так как элементы с нуля отчет ведут ... if s='Code' then ... pCode_attribute := swap2(swap4(swap2(swap2(swap4(p,0),0),0),0),0); // удалить красное writeln(hexw(rc-sizeof(pCode_attribute^.attribute_name_index)), ' attribute_name_index:',pCode_attribute^.attribute_ name_index); writeln(hexw(rc-sizeof(pCode_attribute^.attribute_length)), ' attribute_length:',pCode_attribute^.attribute_leng th); // Удалить {} tCode_attribute = record attribute_name_index : word; // Удалить или задать pGenericAttribute_info^.attribute_name attribute_length : longInt;// Удалить или задать pGenericAttribute_info ^.attribute_length max_stack : word; max_locals : word; code_length : longInt; end; В итоге получаем типа вот этого attribute_name:7 <- Ссылкана 7 элемент “Code” attribute_length:37 <- Длинна 0150h Code: 0156 max_stack:2 0156 max_locals:1 0154 code_length:9 0165h GenericAttribute_info attribute_name:8 attribute_length:10 00 02 00 00 00 03 00 08 00 04 где красным - это уже сам байт-код должен идти, а за ним уже разбор exception_table и естественно если у нас тута будет attribute_name:NN <- Ссылка на элемент “Exceptions” то разбирать её... Ужо голова не соображает abcdef дружище ты если проснесся быстрее меня, замути тему... А то я ужо совсем в осадок выпадаю, кабы косяков не натворил... |
Re: создание MIDletPascal compiler'a
Так после перекоцывания
0150h Code: 0156 max_stack:2 0156 max_locals:1 0154 code_length:9 B2 00 0E 12 10 B6 00 16 B1 <- Байт код //------------------------------ B2 00 0E ....getstatic #000E 12 10 .......ldc #0010 B6 00 16 ....invokevirtual #0016 B1 ..........return //------------------------------ 0165h GenericAttribute_info attribute_name:8 <- Указатель (в нашем случае) на LineNumberTable attribute_length:10 <- Длинна 00 02 00 00 00 03 00 08 00 04 Осталось разобрать LineNumberTable которая в свою очередь уже начинается не с attribute_name_index а с start_pc |
Re: создание MIDletPascal compiler'a
Вощем во...
Код:
{$apptype console} |
Re: создание MIDletPascal compiler'a
исправил работу с double и long переменными
case tag of CONSTANT_Long: write('CONSTANT_Integer :'); CONSTANT_Double: write('CONSTANT_Double :'); end; p := get(p,8 ) ; write(TAB,'_hi: ',longInt(swap4(p,4)^),TAB,'_lo: ',longInt(swap4(p,0)^)); inc(i); // Добавить изменить функцию на такую i := 1; while i <= cf.constant_pool_count-1 do {здесь именно с 1 по cf.constant_pool_count-1} begin write(hexw(rc-1),'h ',i:3,' '); load_const; {загрузка и распознование cp_info} inc(i); end; |
Ответ: создание MIDletPascal compiler'a
satan спасибо! за разбор исходника, сам знаю как это копаться в чужом коде, (иногда проще написать с нуля) да еще с такими до нельзя длинными переменными, но названия не решился сокращать, как в документации, чтоб понятней...
сегодня за компьютер не садился - был на дне города, погода-гадость Администраторам форума: прошу удалить исходный текст из поста #35 т.к. он уже не актуален ____ представляю свои исходники для форматирования исходных текстов на языке Pascal (писался для разовой работы форматирования одного исходника, поэтому не пинать за мелкие огрехи форматирования... и кое-где добавляет лишние запятые ;) ), это некоторые принцыпы переконвертировки исходников с одного языка на другой, которые здесь прозвучали _______PPAS1.pas_______ Код:
{parser *.pas files} _______PPAS2.pas_______ Код:
{parser "END" + ";"} _______PPAS3.pas_______ Код:
{parser - collector} после компиляции всех трех программ запускать bat-файлом: run неформатированный_файл.pas форматированный_файл.pas _______run.bat_______ Код:
запуск |
Ответ: создание MIDletPascal compiler'a
кстати для прикола: компиляции будет поддаваться файл tmp1.$$$ ... интересно былобы посмотреть на того кто получит исходник подобного вида:
.... Код:
n |
Re: создание MIDletPascal compiler'a
Тааааааааакккккк.... СТОП!!!
Вот оно мы и подошли к парсеру и сканеру.... И тут повторяется классическая (даж не ошибка) идея RED BOOK книги драконов и компиляторов Страуструпа и Вирта... Для началу http://exmortis.narod.ru/ суды... Тута исходники на любой вкус, любых компилеров... Парсер в принципе для Delphi можно выдрать из самой Delphi (класс TParser) я в принципе так и делал... Теперь смотри что у тя происходит, так называемый МЕТОД РЕКУРСИВНОГО СПУСКА... procedure UpLevel; begin getToken; //<- берем токен кода case Token.Name of _Program: ;// обрабатываем сроку Program _begin: ;// обрабатываем тело проги _end: ;// завершаем компиляцию end; end; .................. И т.д. Метод хороший но имеет маленький нюансик... Он изночально привязан жостко к исходному языку. А нам надо (Jimon вон просил) исходный синтаксис любого языка... Поэтому луче действовать по Крэншоу, методом подъема. Смотрим логику. Самое главное сейчас получить ассемблерный скажем байт-код Java. Потом останеться только разобрать входной язык. Поэтому надо начать с разбора ВЫРАЖЕНИЙ (Expression) вида a=1+i-22/x+y*22; и получать на выходе уже готовый байт-код потом перейти к разбору переменных и типов... Это естественно заскочит в таблицы, на основе которых и соберётся заголовок. |
Re: создание MIDletPascal compiler'a
Но сначал добьем дизассемблер
добавляем переменную (массив) Код:
var Код:
procedure load_attribute_info; Код:
write(#10#13,TAB); Вот файло какое я коцал MyClass.java interface Constants { int NO=0; int YES=1; } interface Constants2 { int NO=0; int YES=1; } class MyClass implements Constants { public static void main (String [] args) { int i = 0; if (i==NO) System.out.println ("NO"); else System.out.println ("YES"); } } Вот шо из етого вышло Код:
0009h 1 1 CONSTANT_Utf8-Unicode [7] = MyClass видим дизассемблерный код Код:
03 iconst_0 Я тут разобрал токма двубайтовые операции, просто исходников маловат пока, если есть возможность накидайте простых исходников с разными выпендрезами, типа исключит. ситуации и т.д... Чоб протестить. Ассемблирование можно пустить в обратном порядке, тоисть по инструкции просто брать адрес в массиве и собирать исходный класс. |
Ответ: создание MIDletPascal compiler'a
если вы заметили, представляемые исходники, совсем не содержат сложных конструкций, и не используют библиотеки конкретной версии языка... в этом легкость понимания, на каком бы языке не работал читатель. А для полученного продукта - легкость портирования на другие языки.
Хорошая программа в моем понимании - это та, которая выполняет возложенную на нее задачу, написана оптимальными и в тоже время минимальными ресурсами. А не та, которая спроектирована для использования кучи библиотек, функции которых неоптимально взаимодействуют друг с другом, в виду их разнонаправленности и шаблонности, и большинство возможностей которых ни когда не будут использованы в текущей программе. От этого страдает и скорость работы программы и ее размеры Синтаксис Pascal отличается тем, что все его конструкции с легкостью можно переделать в синтаксис basic или C. переобразования в обратную сторону несколько сложнее вот ссылка на последнюю версию <pascals.zip> предлогаемого для модификации компилятора http://www.avhohlov.narod.ru/pascals.zip |
Re: создание MIDletPascal compiler'a
Ну в том и дело, что pascals и context тоже писаны по ред буку, ща я накидаю пост про рек. подъем понятно станет почему луче с низу начинать разбор, и оптимизацию проводить легче...
Кстати Tyni C написано по другому принцпу и читаецо лехше... Но я не настаиваю... |
Ответ: создание MIDletPascal compiler'a
молодец satan! держи плюсик!
вечером попробую отправить свою версию.. |
Re: создание MIDletPascal compiler'a
Спасиб... Тут ишо прада надо добить LineNumberTable и LocalVar...
Но ет дело техники как грица. ХЗ. мож над исправить чо, но пока работаит Код:
else if s='LineNumberTable' then |
Re: создание MIDletPascal compiler'a
Я хренею... Исходник виртуальной машины
Цитата:
|
Ответ: создание MIDletPascal compiler'a
вот собрал шаблонный декомпилер, вида
<строка_название_команды> список_параметров: (1й, 2й, 3й, 4й) в подпрограмме <disasm> - происходит разбор по типам параметров (эт для корректной обработки каждого типа, хотя можно было бы ограничиться 3-мя case условиями) нужно подработать список команд, т.е. напротив каждой команды проставить список параметров для этой команды, я заполнил не все, может и ошибся.. satan поэкспериментируй ;) а я на работу.. насчет эмулятора - там оч.много нужно делать библиотек, - дело не благодарное.. Код:
{$apptype console} |
Re: создание MIDletPascal compiler'a
Гут... Мысль понял... Токма у меня опять в штопор входит...
Надо так, ваще вечером загружу TurboDelphi 2006, оно бесплатное и там помойму с памятью корректнее работает, паетому на ней программы можно и продовать и раздавать... Да и синхронность будет! А машину чоб не мучица из MidpX dll выдрать можно, гы... Ток интерфейс свой прикрутить, я тож гляну чо там за фукции торчат. Теперь пример уже синтаксического анализатора, который разбирает строки вида N +/- ... Где N - цифра, тоесть типа 1+2-3+1-6 или 3+3+5+6-4 ну и т.д... Начнем с азов... Код:
{$APPTYPE CONSOLE} procedure Term; procedure Add; procedure Sub; procedure Expression; И выдает асм листинг формата JVM вот пример разбора строки 1+2-3+4-5+6 Код:
bipush 1 |
Re: создание MIDletPascal compiler'a
abcdef ну нифига у тя буйсво мысли... Гы... нафиг такие замуты, Java asm не работает напрямую с переменными, оно работает с адресами и стеком.
Смори, я разбил на диапазоны 1б операции 2б операции и т.д. а все чо не входит естественно без операнда сразу со стеком работает... Паетому немного у тя надо ldc оператор поправить, для него операнд следучий байт, тоесть он однобайтный оператор... А во смори как из ассемблера токда у меня будет переводица в байт код. Если ща берём байт код и по нему возвращаем оператор Прим: ldc - код 18 или байткод $12 то встретив в коде этот байт мы просто возвращаем его оператор ByteCode[$12] = ldc а кокда мы будем конвертить из ассемблера, то так же будем вычислять опкод, токма поиском в массиве по значению "ldc" который нам вернет $12 - номер в массиве, ну тоесть уже готовый асм - дизасм есть... |
Ответ: создание MIDletPascal compiler'a
все нормуль! мой массив не просто так делался, будем использовать его в компиляторе, он нужен для проверки параметров команды, и.д., а так прийдется большой case писать...
а здесь задал условия в массиве, и все... ввиду складывающихся сложных взаимосвязей между объектами предлагаю разделить Pascal-копилятор на две независимые части: одна из них генерирует текстовый файл с byte-code листингом, другая собирает class-файл на основе полученного файла. 1. это позволить упростить компилятор, сделает его менее привязанным к структуре формирования java byte-code и внутреннего представления class-файлов. 2. стадия сборки будет построенна более оптимально и наглядно 3. в промежутке между стадиями компиляции можно ознакомиться, или вручную подредактировать байт-код |
Re: создание MIDletPascal compiler'a
А ну да... Гы...
А если разбивать, потом не возникнет путанки со всякими там USES??? Кстать, кокда буим парсить, так и так все залетит в таблицы (типа переменных, классов, функций и т.д..) иль ты чо придумал хитрае? |
Ответ: создание MIDletPascal compiler'a
вообщем может кому-нить пригодится можно былобы сделать так:
type jcode=record s:array[0..15] of char; count:byte; end; .... for p:=0 to length-1 do begin write(jbc[...p...].s); p:=get(p,jbc[...p...].count); если нужно выводим байты end; мы потратим в структуре 256 байт, но примерно столько съели бы команды разбора и т.д. предположительная структура асм листинга такова: константы команды_java параметы(ссылка на константу/переменную/число) подпрограмма (параметры) (код) одна команда на строку думаю USES будет только для блока массива констант |
Re: создание MIDletPascal compiler'a
Мля... полна жпа!!!!!!!!!
Пошол в сортир, втыкаю в распечатаный код, прогоняю помалень, вкуриваю... И тут... Асенило... Ептель, ты мутишь не токма дизассемблер, но и декомпилер в одном флаконе, и как тока прогоняю тему все становица на свои места! Ё... Ты так в следучий раз не шути, луче сразу колись шо ишо задумал, гы... Если ишо и деобфускатор, ваще попец полный!!! Ну да ладно, хоть ща догнал тему. Вопрос на засыпку: Скока ишо народу понимает суть дела, и ваще хто ишо тута тусу тусуит??? __________________________________________________ _____________________ satan, призываю общаться на нормальном литературном русском языке и не флудить! |
Ответ: создание MIDletPascal compiler'a
на данный момент главное - это распознать все byte-code коменды и их особенности, потому что ассемблер должен понимать обрабатывать их все. Но для компилятора языка паскаль хватит не более 30-ти штук..
что-то затянулась у нас стадия разбора команд. Участие в экспериментах пока принимать не могу (попросту нет времени). Когда все будет готово ассемблер можно будет создать за 2-а вечера. Насчет профилировщика ты правильно понял satan. Но сейчас нужно получить полностью разбор всех java-команд.. желаю удачи - у тебя хороший багаж знаний! |
Re: создание MIDletPascal compiler'a
Вопщем ассемблер там простой... Работает со стеком,
все мнемокоды вида MNEMO OP1 OP2 - где MNEMO - мнемокод а OP1 OP2 первый и второй оператор (иногда их 10-14) OP1 OP2 - байткод который идет сразу за мнемокодом комманды он может быть адресом переменной в константном пуле или адресом перехода или переменной типа WORD Стек заполняецо сверху в низ и при исполнении команды результат заменяет операнды в стеке на себя Пример 15+25 bipush 15 - грузим число 15 в стек bipush 25 - грузим число 25 в стек iadd - складываем числа в стеке и результат помещаем в верх стека тоесть щас у нас в верху стека число 40 Тоесть все настолько просто, что осталось лишь сказать спасибо ребятам с Java Sun! class calc{ public static void main(String [] args){ int a,i; i=1240; a=i+20; } } Смотрим на код. У нас две переменные, одной из них присваевается ответ. Смотрим код 0000h 11 04 D8 sipush 04D8h 0003h 3D istore_2 0004h 1C iload_2 0005h 10 14 bipush 14h 0007h 60 iadd 0008h 3C istore_1 0009h B1 return Начало кода ПОЛЮБАС оператор, значение 11 – это sipush– Загрузка в стек двухбайтового целого со знаком ,оператор двух байтовый значит следущие два байта – значение переменной 04D8h или 1240 Далее 3D istore_<n> Сохранение целого в локальной переменной Тоесть грузим 1024 в i Ну и тд. Тп. Компиляцию я показывал сверху, проводица она рекурсией причом очень простенькой |
Ответ: создание MIDletPascal compiler'a
список изменений к исходнику предложенному ранее.
1. добавить константу wide 2. заменить подпрограмму disasm; 3. добавить в подпрограмму load_attribute_info переменную "n : integer;" что еще не сделано: "lookupswitch" и некоторые др. команды. _____________________________ техника проверки disassembling'a: 1. скачиваем NMI's Java Code Viewer 6.0 http://www.samsfan.ru/soft/?action=view&id=49&parent=7 2. распаковываем лубую навороченную jar-программку, желательно работающую с double-числами. 3. диассемблируе class файлы Java Code Viewer и нашей программкой, запуск командной строки вида: программа.exe > out.txt 4. сверяем полученные участки кода, если где не состыковка, корректируем алгоритм разбора.. (так сразу видно где лишние байты прихватило) Код:
const |
Часовой пояс GMT +4, время: 03:52. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot