forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Основной форум (http://forum.boolean.name/forumdisplay.php?f=49)
-   -   создание MIDletPascal compiler'a (http://forum.boolean.name/showthread.php?t=6385)

abcdef 20.09.2008 10:07

создание MIDletPascal compiler'a
 
Вложений: 1
Есть предложение, на сайте http://compilers.da.ru/ есть описание компилятора Pascal <PASCALS.ZIP>, который создает стековый байт-код.
Этот исходник можно адаптировать под запись java-кода. Только нужно полное описание java-byte-code и формата class-файлов.

В данный момент у меня работа и редко доступ к интернету, потому самому не осилить... (если Компилятор получиться, то он будет создавать код не хуже MIDletPascal, а размером будет не более 200кб).

C уважением IronWoodcutter.

abcdef 20.09.2008 10:29

Ответ: создание MIDletPascal compiler'a
 
P.S. кто сможет помочь пишите на [email protected]

satan 21.09.2008 02:39

Re: создание MIDletPascal compiler'a
 
Во первых компилятор старый и под свою виртуальную машину, во вторых для компилера для JVM надо описание байт кода JAVA или хотябы (в случае транслятора) хорошее знание JAVA...

odd 21.09.2008 08:15

Ответ: создание MIDletPascal compiler'a
 
Для знания структуры Java-class файла надо покупать там какую-то лицензию и тебе предоставят документацию. Причем лицензий этих несколько видов, причем по разным ценам. Этим, кстати, и объясняется то, что разные Java декомпиляторы (DJ, Cavaj, JavaDec) допускают одинаковые ошибки при декомпиляции. Просто они все созданы на основе дешевой лицензии, а для знания некоторых конструкций уже надо более продвинутая. По-этому ждать когда же они будут нормально декомпилить пустая трата времени. Надо было сразу перед созданием проекта раскошелиться на более приличную сумму.

Phantom 21.09.2008 09:46

Ответ: создание MIDletPascal compiler'a
 
Давайте скинемся всем форумом и купим полную лицензию =)

Romanzes 21.09.2008 10:19

Ответ: создание MIDletPascal compiler'a
 
Мы же не американцы, чтобы что то покупать. Давайте лучше стырим! :crazy:
А если серьезно, я бы пожертвовал несколько долларов для общего дела. Но только несколько :)

Phantom 21.09.2008 11:21

Ответ: создание MIDletPascal compiler'a
 
Я бы и десятку пожертвовал :-D

satan 21.09.2008 12:27

Re: создание MIDletPascal compiler'a
 
Да тырить не надо ничего, все есть, я уже ж подымал тему. Надо знание двух языков Java (для выдергивания байт кода из компилятора который написан на Java) и Pascal-Delphi для оформления самого копмилятора (PE файл), остальное все пишется оч быстро, вернее уже написан (в часности и я писал компилеры), поэтому если интузиазм есть и желание, могу рассказать и показать как пишеца компилер (любой), в добавок потом можно из него сделать оптимизирующий.

abcdef 21.09.2008 13:30

Ответ: создание MIDletPascal compiler'a
 
можно попробовать сделать шаблон для инициализирующих и завершающих секций class-файла, а внутрь добавлять скомпилированный java-код, или же поступить по принципу MIDletPascal заготовить стартующий класс, а к нему дополнительный простого формата class с кодом...

abcdef 21.09.2008 13:46

Ответ: создание MIDletPascal compiler'a
 
MIDletPascal совсем не оптимизирует созданнй код, пишет его как есть, идея создания компилятора ограничивается, возможно только созданием консольной версии, которая сможет создавать class -файлы, т.е. среда_разработки/упаковка/эмулятор - это внешне программы.

Можно сделать в отдельном файле список функций их параметры, чтоб при компиляции проверять исходный текст, т.е. как описываются в Delphi интерфейсы API

abcdef 21.09.2008 14:48

Ответ: создание MIDletPascal compiler'a
 
исходник компилятора, который представил - один из самых простых, грамотно написанных, небольших и в тоже время достаточно функциональный, среди всех которые мне встречались.

Поэтому если его преобразовать,-это будет отличное решение компилятора в исходных кодах, предназначенный для компиляции MIDlet'ов

satan 21.09.2008 19:34

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 сбирай идиномышлеников и в путь...

abcdef 21.09.2008 19:38

создание MIDletPascal compiler'a
 
Вложений: 2
Вот документация, которая есть у меня по java-коду, но этого не достаточно, нужны хотя бы некоторые сходные примеры подобных программ (компилеры/декомпилеры java и т.д.).

Кто может, пожайлуста выкладывайте доку и исходники, не важно на каком языке (pascal/c/java) и ссылку на страничку откуда это было скачано...

а то просто мало свободного времени и очень плохой канал с интернетом

Заранее спасибо!

satan 21.09.2008 20:17

Re: создание MIDletPascal compiler'a
 
Так стоп. Во первых сгоняй на http://forum.boolean.name/showthread.php?t=6028&page=3
там качни Canterbury Pascal for J2ME.В нем отыщи файл SYSTEM.pas. Это уже готовый компилятор в байт код, единственное его переработать под Delphi (просто он там использует Java библиотеки), шаблонные функции в IDE есть...
Вот и все дела... У меня тож с интернетом какай та херня севодня, поетому сложновато общаца...

Piligrim 22.09.2008 07:39

Ответ: создание MIDletPascal compiler'a
 
он и так с Дельфи 2, совместимый.

abcdef 22.09.2008 11:01

Ответ: создание MIDletPascal compiler'a
 
спасибо! это уже что-то, хотя решение не простое, и нужно ставить java.
буду смотреть...
при беглом просмотре скачанных файлов меня заинтересовали исходники, т.е. *.class-файлы ;) из каталога pascal.zip/pascal/pas3/mhc/compiler/

P.S. можно конечно сделать конвертирощик из pascal-исходника в java-исходник, но идея состоит именно в получении готового *.class-файла без дополнительных утилит и программ

satan 22.09.2008 17:32

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 и спецификация...

abcdef 22.09.2008 20:05

Ответ: создание MIDletPascal compiler'a
 
satan сенкс, активное участие и за последнюю ссылку! правда в доке что я выкладывал написано то же, но на английском...
С PE заголовками думаю не стоит лезть в дебри, компилятор делфы, или другой сам все сделает, мы же не соревнуемся в создании самого маленького компилятора ))

satan 22.09.2008 20:15

Re: создание MIDletPascal compiler'a
 
Ну да... просто я к тому, что в принципе база для создания всего что нужно уже есть, причом CLASS файлы луче создавать именно массивом а не структурами, так как это работает в несколько сот раз быстрее... Гы...

Ну чо, изучаем тогда.... помалень...

Piligrim 23.09.2008 07:47

Ответ: создание MIDletPascal compiler'a
 
Товарищ которому авторы МР отдали исходники как в воду канул. Не появляется на форуме и на личку не отвечает.

abcdef 23.09.2008 09:09

Ответ: создание MIDletPascal compiler'a
 
Если товарищ хотел непомню сколько $ за регистрацию,.. то врятли отдаст исходники, даже за зеленые...

Piligrim 23.09.2008 11:23

Ответ: создание MIDletPascal compiler'a
 
Он их уже отдал. Они там хотели их под GPL выложить и пропали.

satan 23.09.2008 19:16

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

abcdef 23.09.2008 19:49

Ответ: создание 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; //Выход из контролируемой области кода

satan 23.09.2008 20:49

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]);
Ну да ето просто вопрос техники...

satan 24.09.2008 02:36

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 или в 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, а затем уже компилировать, можно в принципе и сразу, но писать придется на чистом ООП...

satan 24.09.2008 04:30

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]=”
HelloWorld48 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...

А теперь шо я хотел написать на форуме МП.

Код:

Здаров гандоны и пиндосы!
Шож вы паскуды заныкали исходники MP? Вам мля все наверно денег мало?
Типа считая себя пердячей косточкой вселенной, вы решили, что имеете
право делать все? Никуя... Уроды вы вонючие... Накуй нам теперь нужен
ваш ссаный код, мы решили сами написать систему, которая урыкает нах
вашу паибень, как волк овечку.
Спрашивается, на кой куй постить в форуме такие заявки?
Отвечу, мля за вас – да патаму что вы, как использованный презерватив.
Ни себе ни людям. Если вы думаете, что таким образом вы поднимете себе
рейтинг и уважение, то вы прямехонько, с такими мыслями попадаете пальцем
в попу. Причом хорошо если в свою. Суки вы бл@ продажные, теперь, кокда
мы разрабатываем систему, пусть тока хоть один инглоязычный пес пернет
на своем тухлом языке шо нить по поводу объяснения как работает система.
Не можите поступать по человечиски и к вам будет такой же отношение.
Я нах все сказал!
  МЛЯ!!!


odd 24.09.2008 06:19

Ответ: создание MIDletPascal compiler'a
 
Поддерживаю. С интересом наблюдаю за развитием проекта...

Phantom 24.09.2008 08:43

Ответ: создание MIDletPascal compiler'a
 
Это я такой тупой, что ничего не понимаю, или просто из-за того, что только проснулся? О_о

abcdef 24.09.2008 09:24

Ответ: создание 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. на данный момент у нас нет хоть какого-либо компилятора

dimanche13 24.09.2008 09:59

Ответ: создание MIDletPascal compiler'a
 
Однако, свежо! Интересная веточка, желаю вам удачи в создании русского MP.

jimon 24.09.2008 12:48

Ответ: создание MIDletPascal compiler'a
 
лутче бы написали бы компилятор из какого нибудь более универсального синтаксиса и два транслятора из pascal-подобного и basic-подобного синтаксиса

правда в прочем можно транслировать на java и компилить уже обычным способом

satan 24.09.2008 18:52

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.Ошибка
В первом случае все нормально и пишется код, в третьем выводится ошибка а во втором управление передается точно такой же рекурсивной функции, которая разберёт уже другую строку, например выражение, и т.д...

satan 24.09.2008 21:19

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 файла...

abcdef 25.09.2008 15:21

Ответ: создание MIDletPascal compiler'a
 
вот сбрал приблизительную модель загрузки clsass-файлов, но после считывания константного пула, где-то рвет в размерах считываемых байтов, соответственно неверно заполняются поля размера ниже-следующих структур, посмотрите кто-нить в чем здесь неправ.

формат и доку брал из предоставленной информации.

Программу можно компилировать как и в TurboPascal 7.0, так и Delphi 7.0
только после создания .exe-файла в Delphi антивирус кричит на него что это вирус...


Код:

{$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;
  {}
  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;
  {}
  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;
  {--------------------------}
var
  cf : record      {ClassFile}
    magic              : longInt;
    minor_version      : word;
    major_version      : word;
    constant_pool_count : word;
    cp_info            : pointer; {constant_pool[constant_pool_count - 1];}
    access_flags        : word;
    this_class          : word;
    super_class        : word;
    interfaces_count    : word;
    interfaces          : pointer; {[interfaces_count];}
    fields_count        : word;
    field_info          : pointer; {fields[fields_count];}
    methods_count      : word;
    method_info        : pointer; {methods[methods_count];}
    attributes_count    : word;
    attribute_info      : pointer; {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
  b1,b2,b3,b4 :^byte;
  b          : byte;
begin
  dec(longInt(p),offs+1);
  b1:=p;
  dec(longInt(p));
  b2:=p;
  dec(longInt(p));
  b3:=p;
  dec(longInt(p));
  b4:=p;
  b:=b1^;b1^:=b4^;b4^:=b;
  b:=b2^;b2^:=b3^;b3^:=b;
  swap4 := p;
end;


function getConstStr(index : word) : string;
var
  s    : string;
  i,j,w : word;
  p    :^byte;
begin
  s:='';
  p:=cf.cp_info;
  for i := 1 to cf.constant_pool_count-1 do  {цикл начинается именно с 1, а не 0}
  begin
    if i=index then if (p^ in [CONSTANT_Utf8, CONSTANT_Unicode]) then
    begin
      w:=p^;
      inc(p,2);
      for j := 0 to w-1 do
      begin
        s := s+chr(p^);
        inc(p);
      end;
      getConstStr := s;
      break;
    end;
    case p^ of
      CONSTANT_Class: inc(p,2);
      CONSTANT_Fieldref,CONSTANT_Methodref,CONSTANT_InterfaceMethodref: inc(p,4);
      CONSTANT_String: inc(p,2);
      CONSTANT_Integer,CONSTANT_Float: inc(p,4);
      CONSTANT_Long: inc(p,8);
      CONSTANT_NameAndType: inc(p,4);
      CONSTANT_Utf8, CONSTANT_Unicode:
      begin      {null=$0000, 1b=$0001-$007F,2b=$0008-$07FF,3b=$0800-$FFFF{}
        w:=p^;
        inc(p,2);
        inc(p,w)
      end;
    end;
    getConstStr := s;
  end;
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_InterfaceMethodref:
    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(swap4(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(swap2{4}(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_length);
    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 j := 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 j := 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 j := 0 to pattributes_count^-1 do p:=get(p,1);
  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_name_index)),
      ' attribute_name_index:',pLocalVariableTable_attribute^.attribute_name_index);
    writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.attribute_length)),
      ' attribute_length:',pLocalVariableTable_attribute^.attribute_length);
    writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.local_variable_table_length)),
      ' local_variable_table_length:',pLocalVariableTable_attribute^.local_variable_table_length);
    for j := 0 to pLocalVariableTable_attribute^.local_variable_table_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_pc);
      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 j := 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^.attributes_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^.attributes_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_version),n);
  blockWrite(f,cf.major_version,sizeof(cf.major_version),n);{...}
  reset(f,1);
  rc:=0;
  swap4(get(@cf.magic,sizeof(cf.magic)),0);
  swap2(get(@cf.minor_version,sizeof(cf.minor_version)),0);
  swap2(get(@cf.major_version,sizeof(cf.major_version)),0);
  swap2(get(@cf.constant_pool_count,sizeof(cf.constant_pool_count)),0);
  p:=cf.cp_info;
  for i := 1 to cf.constant_pool_count-1 do {цикл начинается именно с 1, а не 0}
  begin
    write(hexw(rc-1),'h ',i:3,' ');
    load_const;
  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.interfaces_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;
  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;
  end;
  writeln('__________________________');
  writeln(#13#10'-----method_info----');
  swap2(get(@cf.methods_count,sizeof(cf.methods_count)),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;
  end;
  writeln('__________________________');
  writeln('OFFSET:',hexw(rc));
  swap2(get(@cf.attributes_count,sizeof(cf.attributes_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.


satan 25.09.2008 16:20

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

abcdef 25.09.2008 19:02

Ответ: создание MIDletPascal compiler'a
 
хм, сейчас глянул, а некоторые символы исчезли в исходнике...
наверное при конвертировке почему-то потерялись..
function swap2(pointer; offs:integer) : pointer;
должно быть function swap2(P : pointer; offs:integer) : pointer;
тоже самое с function swap4(...

abcdef 25.09.2008 19:14

Ответ: создание MIDletPascal compiler'a
 
да и еще в строке: pGenericAttribute_info:=swap2(swap2{4}(p,0),0);
поставить pGenericAttribute_info:=swap2(swap4(p,0),0);
тестировал, забыл убрать, думал описка там тип 4 байта, я ставил 2..

ПРИМЕЧАНИЕ: компилятор нужно настроить чтобы он не выравнивал переменные в памяти, а то размер структур будет больше, т.е. sizeof(...) и д.р. будет работать некорректно

Piligrim 26.09.2008 14:05

Ответ: создание MIDletPascal compiler'a
 
Цитата:

Сообщение от abcdef (Сообщение 86842)
хм, сейчас глянул, а некоторые символы исчезли в исходнике...
наверное при конвертировке почему-то потерялись..

Если хотите чтобы символы н пропадали, для кусков кода используйте форматирование.
Код:

const
 t : integer;


abcdef 26.09.2008 23:07

Ответ: создание 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.

satan 27.09.2008 00:55

Re: создание MIDletPascal compiler'a
 
а ты какой файл дизазмишь если не секрет? Я простой HelloWord, так у меня что тот, что этот зацикливается на методах а этот теперь еще и на атрибутах...

Мля... Сори, все ок... Я тож наверно от недосыпу тупить уж начал...

satan 27.09.2008 05:05

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 дружище ты если проснесся быстрее меня, замути тему... А то я ужо совсем в осадок выпадаю, кабы косяков не натворил...

satan 27.09.2008 05:48

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

satan 27.09.2008 07:56

Re: создание MIDletPascal compiler'a
 
Вощем во...

Код:

{$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;
  {}
  TAB            = ^I;
  TAB2            = ^I^I;
  TAB3            = ^I^I^I;
  TAB4            = ^I^I^I^I;
  CR              = ^M;
  LF              = ^J;
  {}
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_InterfaceMethodref          : 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;
  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_InterfaceMethodref            :
                                              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            :',TAB,word(swap2(p,0)^));
                                                    end;
  CONSTANT_Fieldref,CONSTANT_Methodref,
  CONSTANT_InterfaceMethodref                    :
                                                    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(TAB,word(swap2(p,2)^),TAB,word(swap2(p,0)^));
                                                    end;
  CONSTANT_String                                :
                                                    begin
                                                      p := get(p,2);
                                                      write('CONSTANT_String            :',TAB,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(TAB,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(TAB,'_hi_',longInt(swap4(p,4)^),TAB,'_lo_',longInt(swap4(p,0)^));
                                                    end;
  CONSTANT_NameAndType                            :
                                                    begin
                                                      p := get(p,4);
                                                      write('CONSTANT_NameAndType      :',TAB,word(swap2(p,2)^),TAB,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,']',TAB,'=',TAB);
                                                      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',TAB2,'GenericAttribute_info');
  p:=get(p,sizeof(pGenericAttribute_info^));
  pGenericAttribute_info:=swap2(swap4(p,0),0);
  s := getConstStr(pGenericAttribute_info^.attribute_name-1);
  writeln(TAB2,'attribute_name    :',TAB2,pGenericAttribute_info^.attribute_name,TAB,'-> ',s);
  writeln(TAB2,'attribute_length  :',TAB2,pGenericAttribute_info ^.attribute_length);

  if s='Code' then
  begin

    writeln(hexw(rc), 'h',TAB,'Code:');
    p := get(p,sizeof(pCode_attribute^));
    pCode_attribute := swap2(swap2(swap4(p,0),0),0);

    writeln(hexw(rc-sizeof(pCode_attribute^.max_stack)),
    'h',TAB2,'max_stack        :',TAB2,pCode_attribute^.max_stack);
    writeln(hexw(rc-sizeof(pCode_attribute^.max_locals)),
    'h',TAB2,'max_locals        :',TAB2,pCode_attribute^.max_locals);
    writeln(hexw(rc-sizeof(pCode_attribute^.code_length)),
    'h',TAB2,'code_length      :',TAB2,pCode_attribute^.code_length);

    write(#10#13,TAB2);
    for n := 0 to pCode_attribute^.code_length-1 do
    begin
      get(p,1);
      write(hex(byte(p^)),' ');
      if ((n+1) mod 8)=0 then write(#10#13,TAB2);
    end;
    writeln;
    writeln;

    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',TAB2,'LocalVariableTable');
    p := get(p,sizeof(pLocalVariableTable_attribute^));
    pLocalVariableTable_attribute := swap2(swap4(swap2(p,0),0),0);
    writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.attribute_name_index)),
    ' attribute_name_index:',pLocalVariableTable_attribute^.attribute_name_index);
    writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.attribute_length)),
    ' attribute_length:',pLocalVariableTable_attribute^. attribute_length);
    writeln(hexw(rc-sizeof(pLocalVariableTable_attribute^.local_variable_table_length)),
    ' local_variable_table_length:',pLocalVariableTable_attribute^.local_variable_table_length);
    for n := 0 to pLocalVariableTable_attribute^.local_variable_table_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_pc);
      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
    for n := 0 to pGenericAttribute_info^.attribute_length-1 do
    begin
      get(p,1);
      //write(hex(byte(p^)),' ');
      inc(p);
    end;
  end{}
  else {don't know... skip atributes}
  begin
    write(#10#13,TAB2);
    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(TAB2,'access_flags      :',TAB2,pfield_info^.access_flags) ;
  writeln(TAB2,'name_index        :',TAB2,pfield_info^.name_index);
  writeln(TAB2,'signature_index  :',TAB2,pfield_info^.signature_index);
  writeln(TAB2,'attributes_count  :',TAB2,pfield_info^.attributes_count,TAB,'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);
  s := getConstStr(pmethod_info^.name_index-1);
  writeln(TAB2,'access_flags      :',TAB2,pmethod_info^.access_flags );
  writeln(TAB2,'name_index        :',TAB2,'[',pmethod_info^.name_index,']',TAB,'-> ',s);
  writeln(TAB2,'signature_index  :',TAB2,pmethod_info^.signature_index);
  writeln(TAB2,'attributes_count  :',TAB2,pmethod_info^.attributes_count,TAB,'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.clas');
  {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_version),n);
  blockWrite(f,cf.major_version,sizeof(cf.major_version),n);{...}
  reset(f,1);

  rc := 0;

  swap4(get(@cf.magic,sizeof(cf.magic)),0);
  swap2(get(@cf.minor_version,sizeof(cf.minor_version)),0);
  swap2(get(@cf.major_version,sizeof(cf.major_version)),0);
  swap2(get(@cf.constant_pool_count,sizeof(cf.constant_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',TAB2,'access_flags      :',TAB2,cf.access_flags);
  swap2(get(@cf.this_class,sizeof(cf.this_class)),0) ;
  writeln(hexw(rc-sizeof(cf.this_class)),'h',TAB2,'this_class        :',TAB2,cf.this_class);
  swap2(get(@cf.super_class,sizeof(cf.super_class)), 0);
  writeln(hexw(rc-sizeof(cf.super_class)),'h',TAB2,'super_class      :',TAB2,cf.super_class);

  writeln;
  swap2(get(@cf.interfaces_count,sizeof(cf.interfaces_count)),0);
  writeln(hexw(rc-sizeof(cf.interfaces_count)),'h',TAB2,'interfaces',TAB,'[',cf.interfaces_count,']',TAB3);
  p := @cf.interfaces^;
  for i := 0 to cf.interfaces_count-1 do
    load_interfaces; {загрузка interfaces}

  writeln;
  swap2(get(@cf.fields_count,sizeof(cf.fields_count) ),0);
  writeln(hexw(rc-sizeof(cf.fields_count)),'h',TAB2,'field_info',TAB,'[',cf.fields_count,']',TAB3);
  p := @cf.field_info^;
  for i := 0 to cf.fields_count-1 do
  begin
    writeln(hexw(rc), 'h',TAB2,'field_info      :',TAB,i:3,'-----------');
    load_field_info; {загрузка field_info}
  end;

  writeln;
  swap2(get(@cf.methods_count,sizeof(cf.methods_count)),0);
  writeln(hexw(rc-sizeof(cf.methods_count)), 'h',TAB2,'method_info',TAB,'[',cf.methods_count,']',TAB3);
  p := @cf.method_info^;
  for i := 0 to cf.methods_count-1 do
  begin
    writeln(hexw(rc),'h',TAB2,'method_info      :',TAB,i:3,'-----------');
    method_info; //загрузка method_info

  end;

  writeln;
  writeln('OFFSET:        ',hexw(rc),'h');
  swap2(get(@cf.attributes_count,sizeof(cf.attributes_count)),0);
  writeln(hexw(rc-sizeof(cf.attributes_count)),'h',TAB2,'attribute_info',TAB,'[',cf.attributes_count,']');
  p := @cf.attribute_info^;
  for i := 0 to cf.attributes_count-1 do
  begin
    load_attribute_info;
    writeln(#10#13'------------------------------------------------------------------');
  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.


satan 27.09.2008 18:54

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;


abcdef 27.09.2008 21:32

Ответ: создание MIDletPascal compiler'a
 
satan спасибо! за разбор исходника, сам знаю как это копаться в чужом коде, (иногда проще написать с нуля) да еще с такими до нельзя длинными переменными, но названия не решился сокращать, как в документации, чтоб понятней...
сегодня за компьютер не садился - был на дне города, погода-гадость

Администраторам форума: прошу удалить исходный текст из поста #35 т.к. он уже не актуален

____
представляю свои исходники для форматирования исходных текстов на языке Pascal (писался для разовой работы форматирования одного исходника, поэтому не пинать за мелкие огрехи форматирования... и кое-где добавляет лишние запятые ;) ),
это некоторые принцыпы переконвертировки исходников с одного языка на другой, которые здесь прозвучали



_______PPAS1.pas_______
Код:

{parser *.pas files}
{by arT  2005}
{e-mail: [email protected]}
var
  inp, out : text;
  eof_inp  : boolean;
  s        : string;
  ch      : char;

procedure add(s : string);
begin
  writeln(out,s);  {s := s+#13#10; BlockWrite(out, s[1], Length(s));}
end;

procedure getch;
begin
  ch := #255;
  if eof_inp = false then
  begin
    read(inp,ch);          {BlockRead(inp, ch, 1);{}
    eof_inp := eof(inp);
  end;
end;

{-----}
procedure getNum;
begin
  repeat
    s := s+ch;
    getch;
  until not (ch in ['0'..'9']);
end;

procedure getHexNum;
begin
  repeat
    if ch in ['A'..'F'] then  inc(ch, (97-65));  {<- loChar}
    s := s+ch;
    getch;
  until not (ch in ['0'..'9','A'..'F','a'..'f']);
end;

procedure tok;
begin
  s := '';
  while (ch <= #32) do  getch;
  case ch of
  'A'..'Z',
  'a'..'z',
  '_'      : begin
                repeat
                  if ch in [#65..#90] then inc(ch, (97-65));
                  s := s+ch;
                  getch;
                until not (ch in ['0'..'9','_','A'..'Z','a'..'z']);
              end;
  '0'..'9' : begin
                repeat
                  getNum;
                until (ch<>'.');
              end;
  '$'      : getHexNum;
  '''','#' : begin
                repeat
                  if ch = '#' then
                  begin
                    repeat
                      s := s+ch;
                      getch;
                      if ch <> '$' then getNum
                        else getHexNum;
                    until ch <> '#';
                  end
                  else
                  begin
                    repeat
                      repeat
                        s := s+ch;
                        getch;
                      until ch = '''';
                      s := s+ch;
                      getch;
                    until ch <> '''';
                  end;
                until not (ch in ['''','#']);
              end;
  ':'      : begin
                s := ch;
                getch;
                if ch = '=' then
                begin
                  s := s+ch;
                  getch;
                end;
              end;
  '>'      : begin
                s := ch;
                getch;
                if ch = '=' then
                begin
                  s := s+ch;
                  getch;
                end;
              end;
  '<'      : begin
                s := ch;
                getch;
                if (ch = '=') or (ch = '>') then
                begin
                  s := s+ch;
                  getch;
                end;
              end;
  '.'      : begin
                s := ch;
                getch;
                if (ch = '.') or (ch = ')') then
                begin
                  s := s+ch;
                  getch;
                end;
              end;
  '('      : begin
                s := ch;
                getch;
                if (ch = '.') then
                begin
                  s := s+ch;
                  getch;
                end
                else if (ch = '*') then
                begin
                  repeat
                    while ch <> '*' do
                    begin
                      s := s+ch;
                      getch;
                      if ch = #13 then
                      begin
                        add(s);
                        s := '';
                        getch;
                        getch;
                      end;
                    end;
                    s := s+ch;
                    getch;
                  until ch = ')';
                  s := s+ch;
                  getch;
                end;
              end;
  '{'      : begin
                repeat
                  s := s+ch;
                  getch;
                  if ch = #13 then
                  begin
                    add(s);
                    s := '';
                    getch;
                    getch;
                  end;
                until ch = '}';
                s := s+ch;
                getch;
              end;
  else      begin
                s := ch;
                getch;
              end;
  end;
end;
{-----}

begin
  if paramCount <> 2 then
  begin
    writeLn('parser for PAS files'#13#$0A+
            'ver 0.0.1  by arT    e-mail: [email protected]'#13#10#10+
            'Usage:  PPAS1 <in.pas> <out.pas>');
    halt;
  end;
  s := paramStr(1);
  assign(inp, s);
  {$I-} reset(inp); {$I+}
  if IOresult = 0 then
  begin
    assign(out, ParamStr(2));
    {$I-} rewrite(out); {$I+}
    if IOresult = 0 then
    begin
      eof_inp := false;
      add('{'+s+'}');
      getch;
      repeat
        tok;
        add(s);
      until eof_inp;
      close(out);
    end
      else writeLn('Error:  can''t  create file <pas.pas>');
    close(inp);
  end
    else writeLn('Error:  file <'+s+'> not found !');
end.


_______PPAS2.pas_______
Код:

{parser "END" + ";"}
{by arT  2005}
{e-mail: [email protected]}
{поставить после каждого "END" символ ";", кроме случая "ELSE" и последнего "END"}
var
  f,f2 : text;
  s,s2 : string;
  ok  : boolean;
begin
  if paramCount<>2 then
  begin
    writeln('parse "END" + ";"'#13#$0A+
            'ver 0.0.1  by arT    e-mail: [email protected]'#13#10#10+
            'Usage:  PPAS2 <in.pas> <out.pas>');
    halt;
  end;
  assign(f,paramStr(1));
  {$I-}reset(f);{$I+}
  if IOresult<>0 then
  begin
    writeln('file <'+paramStr(1)+'> not found');
    halt;
  end;
  assign(f2,paramStr(2));
  rewrite(f2);
  ok := false;
  s2 := '';
  while not eof(f) do
  begin
    readln(f,s);
    {if ok and ((s<>'else') or (s<>'.')) then  writeln(f2,';');
    ok := (s='end');}
    if (s='end') then if (s2<>';') then writeln(f2,';');
    writeln(f2,s);
    s2 := s;
  end;
  close(f2);
  close(f);
end.


_______PPAS3.pas_______
Код:

{parser - collector}
{by arT  2005}
{e-mail: [email protected]}
const
  _vars  = 1;
  _proc  = 2;
  _prog  = 3;
var
  f1,f2 : text;
  str,s : string;
  p,t  : integer;


procedure out;
var
  i : integer;
begin
  if length(str)>0 then
  begin
    for i := 1 to p do  str := ' '+str;
    writeLn(f2,str);
  end;
  str := '';
end;


procedure add;
var
  b1,b2 : boolean;
begin
  if length(str)+length(s) > 80 then out;
  b1 := (length(str)>0) and (str[length(str)-1] in ['A'..'Z','a'..'z','0'..'9',' ']);
  b2 := (length(s)>0) and (s[1] in ['A'..'Z','a'..'z','0'..'9',' ','{']);
  if not(b1 and b2) then str := copy(str,1,length(str)-1); {remove spase in the end}
  str := str+s+' ';
end;


procedure pars;
begin
  if eof(f1) then
  begin
    add;
    out;
    close(f2);
    halt;
  end;
  readln(f1,s);
  {-----------}
  if (s='label') or (s='const') or (s='type') or (s='var') then
  begin
    t := _vars;
    out;
    p := 0;
    add;
    out;
    p := 2;
  end else
  if (s='procedure') or (s='function') then
  begin
    t := _proc;
    out;
    add;
    p := 0;
  end else
  if (s='begin') then
  begin
    out;
    add;
    if t<>_prog then p:=0;
    t:=_prog;
    out;
    inc(p,2);
    repeat
      pars;
    until (s='end');
    dec(p,2);
    pars;
    out;
  end else
  if (s='end') then
  begin
    out;
    add;
  end else
  if (s='repeat') then
  begin
    out;
    add;
    out;
    inc(p,2);
    repeat
      pars;
    until s='until';
    pars;
    dec(p,2);
  end else
  if (s='until') then
  begin
    out;
    add;
  end else
  if (s='case') then
  begin
    out;
    add;
    out;
    inc(p,2);
    repeat
      pars;
    until s='end';
    dec(p,2);
    pars;
    out;
  end else
  if (s='then') then
  begin
    add;
    repeat
      pars;
    until s=';';
  end else
  if (s='else') then
  begin
    out;
    inc(p,2);
    add;
    repeat
      pars;
    until (s=';');
    dec(p,2);
  end else
  if (s='do') then
  begin
    add;
    repeat
      pars;
    until s=';';
  end else
  if (s=';') then
  begin
    add;
    out;
  end else
  if (s[1]='{') then
  begin
    add;
    out;
  end else
  begin
    add;
  end;
end;

begin
  if paramCount <> 2 then
  begin
    WriteLn('parser - collector for PAS files'#13#$0A+
            'ver 0.0.1  by arT    e-mail: [email protected]'#13#10#10+
            'Usage:  PPAS3 <in.pas> <out.pas>');
    Halt;
  end;
  assign(f1,ParamStr(1));
  {$I-} reset(f1); {$I+}
  if IOresult = 0 then
  begin
    assign(f2,ParamStr(2));
    rewrite(f2);
    p := 0;
    str := '';
    t := _vars;
    repeat
      pars;
    until false;
  end
    else writeLn('error: file  <pas.pas> not found');
end.


после компиляции всех трех программ запускать bat-файлом:
run неформатированный_файл.pas форматированный_файл.pas

_______run.bat_______
Код:

запуск
@echo off
echo usage: RUN  parss prog.pas  format.pas
ppas1 %1 tmp1.$$$
ppas2 tmp1.$$$ tmp2.$$$
ppas3 tmp2.$$$ %2
del tmp1.$$$
del tmp2.$$$


abcdef 27.09.2008 21:45

Ответ: создание MIDletPascal compiler'a
 
кстати для прикола: компиляции будет поддаваться файл tmp1.$$$ ... интересно былобы посмотреть на того кто получит исходник подобного вида:

....
Код:

n
:=
word
(
swap2
(
p
,
0
)
^
)
;
write
(
'CONSTANT_Utf8-Unicode ['
,
n
,
']='

....

satan 28.09.2008 04:43

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;
и получать на выходе уже готовый байт-код
потом перейти к разбору переменных и типов... Это естественно заскочит в таблицы, на основе которых и соберётся заголовок.

satan 28.09.2008 08:09

Re: создание MIDletPascal compiler'a
 
Но сначал добьем дизассемблер

добавляем переменную (массив)
Код:

var
  ByteCode: array [1..209] of String = (
    'aconst_null',    'iconst_m1',      'iconst_0',            'iconst_1',        'iconst_2',            'iconst_3',
    'iconst_4',        'iconst_5',        'lconst_0',            'lconst_1',        'fconst_0',            'fconst_1',
    'fconst_2',        'dconst_0',        'dconst_1',            'bipush',          'sipush',              'ldc1',
    'ldc2',            'ldc2w',          'iload',              'lload',          'fload',              'dload',
    'aload',          'iload_0',        'iload_1',            'iload_2',        'iload_3',            'lload_0',
    'lload_1',        'lload_2',        'lload_3',            'fload_0',        'fload_1',            'fload_2',
    'fload_3',        'dload_0',        'dload_1',            'dload_2',        'dload_3',            'aload_0',
    'aload_1',        'aload_2',        'aload_3',            'iaload',          'laload',              'faload',
    'daload',          'aaload',          'baload',              'caload',          'saload',              'istore',
    'lstore',          'fstore',          'dstore',              'astore',          'istore_0',            'istore_1',
    'istore_2',        'istore_3',        'lstore_0',            'lstore_1',        'lstore_2',            'lstore_3',
    'fstore_0',        'fstore_1',        'fstore_2',            'fstore_3',        'dstore_0',            'dstore_1',
    'dstore_2',        'dstore_3',        'astore_0',            'astore_1',        'astore_2',            'astore_3',
    'iastore',        'lastore',        'fastore',            'dastore',        'aastore',            'bastore',
    'castore',        'sastore',        'pop',                'pop2',            'dup',                'dup_x1',
    'dup_x2',          'dup2',            'dup2_x1',            'dup2_x2',        'swap',                'iadd',
    'ladd',            'fadd',            'dadd',                'isub',            'lsub',                'fsub',
    'dsub',            'imul',            'lmul',                'fmul',            'dmul',                'idiv',
    'ldiv',            'fdiv',            'ddiv',                'irem',            'lrem',                'frem',
    'drem',            'ineg',            'leg',                'fneg',            'dneg',                'ishl',
    'lshl',            'ishr',            'lshr',                'iushr',          'lushr',              'iand',
    'land',            'ior',            'lor',                'ixor',            'lxor',                'iinc',
    'i2l',            'i2f',            'i2d',                'l2i',            'l2f',                'l2d',
    'f2i',            'f2l',            'f2d',                'd2i',            'd2l',                'd2f',
    'int2byte',        'int2char',        'int2short',          'lcmp',            'fcmpl',              'fcmpg',
    'dcmpl',          'dcmpg',          'ifeq',                'ifne',            'iflt',                'ifge',
    'ifgt',            'ifle',            'if_icmpeq',          'if_icmpne',      'if_icmplt',          'if_icmpge',
    'if_icmpgt',      'if_icmple',      'if_acmpeq',          'if_acmpne',      'goto',                'jsr',
    'ret',            'tableswitch',  'lookupswitch',        'ireturn',        'lreturn',            'freturn',
    'dreturn',        'areturn',        'return',              'getstatic',      'putstatic',          'getfield',
    'putfield',        'invokevirtual','invokenonvirtual',    'invokestatic',    'invokeinterface',    '',
    'new',            'newarray',        'anewarray',          'arraylength',    'athrow',              'checkcast',
    'instanceof',      'monitorenter',    'monitorexit',        'wide',            'multianewarray',      'ifnull',
    'ifnonnull',      'goto_w',          'jsr_w',              'breakpoint',      '',                    '',
    '',                '',                '',                    '',                'ret_w'
    );

немного изменяем нашу фукцию

Код:

procedure load_attribute_info;
var
  op,p1,p2: byte;
begin

и тыкаем (где разбор кода следучее)
Код:

write(#10#13,TAB);
   
    n := 0;
    while n < pCode_attribute^.code_length do
    begin
      get(p,1);
      op:= byte(p^);
      write(hexw(n),'h',TAB,hex(byte(p^)),' ');
      case byte(p^) of
          18                : // 1
                              begin
                                get(p,1); p1:=byte(p^); write(hex(byte(p^)),' ');
                                write(TAB2,ByteCode[op],' ',hex(p1),'h');
                                inc(n);
                              end;
          17,19,20,132,
          153..168,178..184,
          187,189,192,193,
          198,199,209      : // 2
                              begin
                                get(p,1); p1:=byte(p^); write(hex(byte(p^)),' ');
                                get(p,1); p2:=byte(p^); write(hex(byte(p^)),' ');
                                write(TAB,ByteCode[op],' ',hex(p1),hex(p2),'h');
                                inc(n,2);
                              end;
          197              : // 3
                              begin
                                inc(n,3);
                              end;
          185,200,201      : // 4
                              begin
                                inc(n,4);
                              end;
          171              : // 10
                              begin

                              end;
          170                : // 14
                              begin

                              end;
      else
        write(TAB2,ByteCode[byte(p^)]);
      end;
      inc(n);
      write(#10#13,TAB);
    end;
    writeln;
    writeln;

И вот мы ужо имеем дизассемблер!!!

Вот файло какое я коцал 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
0013h  2  7 CONSTANT_Class            :      1
0016h  3  1 CONSTANT_Utf8-Unicode [16] =      java/lang/Object
0029h  4  7 CONSTANT_Class            :      3
002Ch  5  1 CONSTANT_Utf8-Unicode [9]  =      Constants
0038h  6  7 CONSTANT_Class            :      5
003Bh  7  1 CONSTANT_Utf8-Unicode [4]  =      main
0042h  8  1 CONSTANT_Utf8-Unicode [22] =      ([Ljava/lang/String;)V
005Bh  9  1 CONSTANT_Utf8-Unicode [4]  =      Code
0062h  10  1 CONSTANT_Utf8-Unicode [15] =      LineNumberTable
0074h  11  1 CONSTANT_Utf8-Unicode [3]  =      out
007Ah  12  1 CONSTANT_Utf8-Unicode [21] =      Ljava/io/PrintStream;
0092h  13 12 CONSTANT_NameAndType      :      11      12
0097h  14  1 CONSTANT_Utf8-Unicode [16] =      java/lang/System
00AAh  15  7 CONSTANT_Class            :      14
00ADh  16  9 CONSTANT_Fieldref          :      15      13
00B2h  17  1 CONSTANT_Utf8-Unicode [2]  =      NO
00B7h  18  8 CONSTANT_String            :      17
00BAh  19  1 CONSTANT_Utf8-Unicode [7]  =      println
00C4h  20  1 CONSTANT_Utf8-Unicode [21] =      (Ljava/lang/String;)V
00DCh  21 12 CONSTANT_NameAndType      :      19      20
00E1h  22  1 CONSTANT_Utf8-Unicode [19] =      java/io/PrintStream
00F7h  23  7 CONSTANT_Class            :      22
00FAh  24 10 CONSTANT_Methodref        :      23      21
00FFh  25  1 CONSTANT_Utf8-Unicode [3]  =      YES
0105h  26  8 CONSTANT_String            :      25
0108h  27  1 CONSTANT_Utf8-Unicode [6]  =      <init>
0111h  28  1 CONSTANT_Utf8-Unicode [3]  =      ()V
0117h  29 12 CONSTANT_NameAndType      :      27      28
011Ch  30 10 CONSTANT_Methodref        :      4      29
0121h  31  1 CONSTANT_Utf8-Unicode [10] =      SourceFile
012Eh  32  1 CONSTANT_Utf8-Unicode [12] =      MyClass.java

013Eh          access_flags      :            32
0140h          this_class        :            2
0142h          super_class      :            4

0144h          interfaces      [1]            6 ->    [5]Constants,

0148h          field_info      [0]

014Ah          method_info    [2]
014Ch          method_info      :      0-----------
                access_flags      :            9
                name_index        :            [7]    -> main
                signature_index  :            8
                attributes_count  :            1      offs:[0154h]
0154h          GenericAttribute_info
                attribute_name    :            9      -> Code
                attribute_length  :            66
015Ah  Code:
0160h          max_stack        :            2
0160h          max_locals        :            2
015Eh          code_length      :            26

        0000h  03              iconst_0
        0001h  3C              istore_1
        0002h  1B              iload_1
        0003h  9A 00 0E        ifne 000Eh
        0006h  B2 00 10        getstatic 0010h
        0009h  12 12          ldc1 12h
        000Bh  B6 00 18        invokevirtual 0018h
        000Eh  A7 00 0B        goto 000Bh
        0011h  B2 00 10        getstatic 0010h
        0014h  12 1A          ldc1 1Ah
        0016h  B6 00 18        invokevirtual 0018h
        0019h  B1              return


0180h          GenericAttribute_info
                attribute_name    :            10      -> LineNumberTable
                attribute_length  :            22


019Ch          method_info      :      1-----------
                access_flags      :            0
                name_index        :            [27]    -> <init>
                signature_index  :            28
                attributes_count  :            1      offs:[01A4h]
01A4h          GenericAttribute_info
                attribute_name    :            9      -> Code
                attribute_length  :            33
01AAh  Code:
01B0h          max_stack        :            1
01B0h          max_locals        :            1
01AEh          code_length      :            5

        0000h  2A              aload_0
        0001h  B7 00 1E        invokenonvirtual 001Eh
        0004h  B1              return


01BBh          GenericAttribute_info
                attribute_name    :            10      -> LineNumberTable
                attribute_length  :            10



OFFSET:        01CBh
01CBh          attribute_info  [1]
01CDh          GenericAttribute_info
                attribute_name    :            31      -> SourceFile
                attribute_length  :            2

                00 20



видим дизассемблерный код

Код:

03              iconst_0
 3C              istore_1
 1B              iload_1
 9A 00 0E        ifne 000Eh
 B2 00 10        getstatic 0010h
 12              ldc1
 12              ldc1
 B6 00 18        invokevirtual 0018h
 A7 00 0B        goto 000Bh
 B2 00 10        getstatic 0010h
 12              ldc1
 1A              iload_0
 B6 00 18        invokevirtual 0018h
 B1              return

ЗЫ...

Я тут разобрал токма двубайтовые операции, просто исходников маловат пока, если есть возможность накидайте простых исходников
с разными выпендрезами, типа исключит. ситуации и т.д... Чоб протестить.

Ассемблирование можно пустить в обратном порядке, тоисть по инструкции просто брать адрес в массиве
и собирать исходный класс.

abcdef 28.09.2008 09:12

Ответ: создание MIDletPascal compiler'a
 
если вы заметили, представляемые исходники, совсем не содержат сложных конструкций, и не используют библиотеки конкретной версии языка... в этом легкость понимания, на каком бы языке не работал читатель. А для полученного продукта - легкость портирования на другие языки.

Хорошая программа в моем понимании - это та, которая выполняет возложенную на нее задачу, написана оптимальными и в тоже время минимальными ресурсами.
А не та, которая спроектирована для использования кучи библиотек, функции которых неоптимально взаимодействуют друг с другом, в виду их разнонаправленности и шаблонности, и большинство возможностей которых ни когда не будут использованы в текущей программе. От этого страдает и скорость работы программы и ее размеры

Синтаксис Pascal отличается тем, что все его конструкции с легкостью можно переделать в синтаксис basic или C. переобразования в обратную сторону несколько сложнее

вот ссылка на последнюю версию <pascals.zip> предлогаемого для модификации компилятора http://www.avhohlov.narod.ru/pascals.zip

satan 28.09.2008 09:32

Re: создание MIDletPascal compiler'a
 
Ну в том и дело, что pascals и context тоже писаны по ред буку, ща я накидаю пост про рек. подъем понятно станет почему луче с низу начинать разбор, и оптимизацию проводить легче...

Кстати Tyni C написано по другому принцпу и читаецо лехше...
Но я не настаиваю...

abcdef 28.09.2008 09:38

Ответ: создание MIDletPascal compiler'a
 
молодец satan! держи плюсик!
вечером попробую отправить свою версию..

satan 28.09.2008 09:54

Re: создание MIDletPascal compiler'a
 
Спасиб... Тут ишо прада надо добить LineNumberTable и LocalVar...
Но ет дело техники как грица.

ХЗ. мож над исправить чо, но пока работаит

Код:

  else if s='LineNumberTable' then
  begin
      p:=get(p,2);
      lt:=word(swap2(p,0)^);
      writeln(TAB2,'line_number_table_length:',TAB,lt,#10#13);
      for i := 0 to lt-1 do
      begin
        p:=get(p,2);
        writeln(TAB3,'start_pc    :',TAB,hexw(word(swap2(p,0)^)));
        p:=get(p,2);
        writeln(TAB3,'line_number :',TAB,hexw(word(swap2(p,0)^)));
      end;
  end


satan 28.09.2008 13:07

Re: создание MIDletPascal compiler'a
 
Я хренею... Исходник виртуальной машины

Цитата:

do {
выбор байт кода операции
выполнение действия в зависимости от значения кода
} while (еще нужно выполнять);

Мож потом замутим?

abcdef 29.09.2008 06:05

Ответ: создание MIDletPascal compiler'a
 
вот собрал шаблонный декомпилер, вида
<строка_название_команды> список_параметров: (1й, 2й, 3й, 4й)
в подпрограмме <disasm> - происходит разбор по типам параметров (эт для корректной обработки каждого типа, хотя можно было бы ограничиться 3-мя case условиями)

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

satan поэкспериментируй ;) а я на работу..
насчет эмулятора - там оч.много нужно делать библиотек, - дело не благодарное..

Код:

{$apptype console}
{$S+}
type
  tcode = record
    s : array[0..15] of char;
    b : array[0..3] of byte;
  end;
const
  nb  = 1;  {1байт целое беззнаковое}
  ns  = 2;  {1байт целое знаковое}
  nw  = 3;  {2байта целое беззнаковое}
  ni  = 4;  {2байта целое знаковое}
  cb  = 5;  {1байт индекс в константном пуле }
  cw  = 6;  {2байта индекс в константном пуле 2-х байтовой константы}
  cl  = 7;  {2байта индекс в константном пуле 2-х словной константы}
  cp  = 8;  {2байта индекс в константном пуле Получение статического поля класса  Элементом константного пула
            будет поле ссылки на статическое поле класса - полями шириной как 64-бита так и 32-бита}
  cv  = 9;  {2байта индекс в константном пуле текущего класса - сигнатура метода}
  cn  = 10; {2байта - конструирование индекса в константном пуле}
  ck  = 11; {2байта индекс на класс}
  cs  = 12; {2байта индекс на строку}
  lii  = 13; {загрузка целого из локальной переменной}
  lil  = 14; {загрузка длинного целого из локальной переменной}
  lif  = 15; {загрузка вещественного одинарной точности из локальной переменной}
  lid  = 16; {загрузка вещественного двойной точности из локальной переменной}
  lio  = 17; {загрузка объектной ссылки из локальной переменной}
  sii  = 18; {сохранение целого значения в локальной переменной}
  sil  = 19; {сохранение длинного целого в локальной переменной}
  sif  = 20; {Сохранение вещественного одинарной точности в локальной переменной}
  sid  = 21; {Сохранение двойного вещественного в локальной переменной}
  sio  = 22; {Сохранение объектной ссылки в локальной переменной}
  ac  = 23; {Увеличение локальной переменной на константу}
  of2  = 24; {16-битное знаковое смещение}
  of4  = 25; {32-битное знаковое смещение}
  ofp2 = 26; {16-битное знаковое смещение Переход на подпрограмму}
  ofp4 = 27; {32-битное знаковое смещение Переход на подпрограмму}
  rtb  = 28; {8-битный адрес Возврат из подпрограммы - адрес возврата}
  rtw  = 29; {16-битный адрес возврата}
  {-----------------------------------}
  jbc : array[0..255] of tcode = (
{00}  (s:'nop            '; b:(0,0,0,0)),      {Ничего не делает}
{01}  (s:'aconst_null    '; b:(0,0,0,0)),      {Загрузка в стек null ( пустой ссылки на объект)}
{02}  (s:'iconst_m1      '; b:(0,0,0,0)),      {Загрузка целочисленной константы -1}
{03}  (s:'iconst_0        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 0}
{04}  (s:'iconst_1        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 1}
{05}  (s:'iconst_2        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 2}
{06}  (s:'iconst_3        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 3}
{07}  (s:'iconst_4        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 4}
{08}  (s:'iconst_5        '; b:(0,0,0,0)),      {Загрузка целочисленной константы 5}
{09}  (s:'lconst_0        '; b:(0,0,0,0)),      {Загрузка длинной целочисленной константы 0}
{0A}  (s:'lconst_1        '; b:(0,0,0,0)),      {Загрузка длинной целочисленной константы 1}
{0B}  (s:'fconst_0        '; b:(0,0,0,0)),      {Загрузка вещественного числа одинарной точности 0}
{0C}  (s:'fconst_1        '; b:(0,0,0,0)),      {Загрузка вещественного числа одинарной точности 1}
{0D}  (s:'fconst_2        '; b:(0,0,0,0)),      {Загрузка вещественного числа одинарной точности 2}
{0E}  (s:'dconst_0        '; b:(0,0,0,0)),      {Загрузка вещественного числа двойной точности 0}
{0F}  (s:'dconst_1        '; b:(0,0,0,0)),      {Загрузка вещественного числа двойной точности 1}
{10}  (s:'bipush          '; b:(nb,0,0,0)),    {1,Загрузка в стек однобайтового целого со знаком}
{11}  (s:'sipush          '; b:(ni,0,0,0)),    {2,Загрузка в стек двухбайтового целого со знаком}
{12}  (s:'ldc1            '; b:(cb,0,0,0)),    {1,Загрузка в стек элемента из константного пула}
{13}  (s:'ldc2            '; b:(cw,0,0,0)),    {2,Загрузка в стек элемента из константного пула}
{14}  (s:'ldc2w          '; b:(cl,1,0,0)),    {2,Загрузка в стек длинного целого или двойного
                                                вещественного значения из константного пула}
{15}  (s:'iload          '; b:(lii,0,0,0)),    {1,Загрузка целого из локальной переменной}
{16}  (s:'lload          '; b:(lil,0,0,0)),    {1,Загрузка длинного целого из локальной переменной}
{17}  (s:'fload          '; b:(lif,0,0,0)),    {1,Загрузка вещественного одинарной точности из локальной переменной}
{18}  (s:'dload          '; b:(lid,0,0,0)),    {1,Загрузка вещественного двойной точности из локальной переменной}
{19}  (s:'aload          '; b:(lio,0,0,0)),    {1,Загрузка объектной ссылки из локальной переменной}
{1A}  (s:'iload_0        '; b:(0,0,0,0)),      {Загрузка целого из локальной переменной 0}
{1B}  (s:'iload_1        '; b:(0,0,0,0)),      {Загрузка целого из локальной переменной 1}
{1C}  (s:'iload_2        '; b:(0,0,0,0)),      {Загрузка целого из локальной переменной 2}
{1D}  (s:'iload_3        '; b:(0,0,0,0)),      {Загрузка целого из локальной переменной 3}
{1E}  (s:'lload_0        '; b:(0,0,0,0)),      {Загрузка длинного целого из локальной переменной 0}
{1F}  (s:'lload_1        '; b:(0,0,0,0)),      {Загрузка длинного целого из локальной переменной 1}
{20}  (s:'lload_2        '; b:(0,0,0,0)),      {Загрузка длинного целого из локальной переменной 2}
{21}  (s:'lload_3        '; b:(0,0,0,0)),      {Загрузка длинного целого из локальной переменной 3}
{22}  (s:'fload_0        '; b:(0,0,0,0)),      {Загрузка вещественного одинарной точности из локальной переменной 0}
{23}  (s:'fload_1        '; b:(0,0,0,0)),      {Загрузка вещественного одинарной точности из локальной переменной 1}
{24}  (s:'fload_2        '; b:(0,0,0,0)),      {Загрузка вещественного одинарной точности из локальной переменной 2}
{25}  (s:'fload_3        '; b:(0,0,0,0)),      {Загрузка вещественного одинарной точности из локальной переменной 3}
{26}  (s:'dload_0        '; b:(0,0,0,0)),      {Загрузка вещественного двойной точности из локальной переменной 0}
{27}  (s:'dload_1        '; b:(0,0,0,0)),      {Загрузка вещественного двойной точности из локальной переменной 1}
{28}  (s:'dload_2        '; b:(0,0,0,0)),      {Загрузка вещественного двойной точности из локальной переменной 2}
{29}  (s:'dload_3        '; b:(0,0,0,0)),      {Загрузка вещественного двойной точности из локальной переменной 3}
{2A}  (s:'aload_0        '; b:(0,0,0,0)),      {Загрузка объектной ссылки из локальной переменной 0}
{2B}  (s:'aload_1        '; b:(0,0,0,0)),      {Загрузка объектной ссылки из локальной переменной 1}
{2C}  (s:'aload_2        '; b:(0,0,0,0)),      {Загрузка объектной ссылки из локальной переменной 2}
{2D}  (s:'aload_3        '; b:(0,0,0,0)),      {Загрузка объектной ссылки из локальной переменной 3}
{2E}  (s:'iaload          '; b:(0,0,0,0)),      {Загрузка целого из массива}
{2F}  (s:'laload          '; b:(0,0,0,0)),      {Загрузка длинного целого из массива}
{30}  (s:'faload          '; b:(0,0,0,0)),      {Загрузка вещественного из массива}
{31}  (s:'daload          '; b:(0,0,0,0)),      {Загрузка двойного вещественного из массива}
{32}  (s:'aaload          '; b:(0,0,0,0)),      {Загрузка объектной ссылки из массива}
{33}  (s:'baload          '; b:(0,0,0,0)),      {Загрузка байта со знаком из массива}
{34}  (s:'caload          '; b:(0,0,0,0)),      {Загрузка символа из массива}
{35}  (s:'saload          '; b:(0,0,0,0)),      {Загрузка короткого из массива}
{36}  (s:'istore          '; b:(sii,0,0,0)),    {1,Сохранение целого значения в локальной переменной}
{37}  (s:'lstore          '; b:(sil,0,0,0)),    {1,Сохранение длинного целого в локальной переменной}
{38}  (s:'fstore          '; b:(sif,0,0,0)),    {1,Сохранение вещественного одинарной точности в локальной переменной}
{39}  (s:'dstore          '; b:(sid,0,0,0)),    {1,Сохранение двойного вещественного в локальной переменной}
{3A}  (s:'astore          '; b:(sio,0,0,0)),    {1,Сохранение объектной ссылки в локальной переменной}
{3B}  (s:'istore_0        '; b:(0,0,0,0)),      {Сохранение целого в локальной переменной 0}
{3C}  (s:'istore_1        '; b:(0,0,0,0)),      {Сохранение целого в локальной переменной 1}
{3D}  (s:'istore_2        '; b:(0,0,0,0)),      {Сохранение целого в локальной переменной 2}
{3E}  (s:'istore_3        '; b:(0,0,0,0)),      {Сохранение целого в локальной переменной 3}
{3F}  (s:'lstore_0        '; b:(0,0,0,0)),      {Сохранение длинного целого в локальной переменной 0}
{40}  (s:'lstore_1        '; b:(0,0,0,0)),      {Сохранение длинного целого в локальной переменной 1}
{41}  (s:'lstore_2        '; b:(0,0,0,0)),      {Сохранение длинного целого в локальной переменной 2}
{42}  (s:'lstore_3        '; b:(0,0,0,0)),      {Сохранение длинного целого в локальной переменной 3}
{43}  (s:'fstore_0        '; b:(0,0,0,0)),      {Сохранение вещественного одинарной точности в локальной переменной 0}
{44}  (s:'fstore_1        '; b:(0,0,0,0)),      {Сохранение вещественного одинарной точности в локальной переменной 1}
{45}  (s:'fstore_2        '; b:(0,0,0,0)),      {Сохранение вещественного одинарной точности в локальной переменной 2}
{46}  (s:'fstore_3        '; b:(0,0,0,0)),      {Сохранение вещественного одинарной точности в локальной переменной 3}
{47}  (s:'dstore_0        '; b:(0,0,0,0)),      {Сохранение двойного вещественного в локальной переменной 0}
{48}  (s:'dstore_1        '; b:(0,0,0,0)),      {Сохранение двойного вещественного в локальной переменной 1}
{49}  (s:'dstore_2        '; b:(0,0,0,0)),      {Сохранение двойного вещественного в локальной переменной 2}
{4A}  (s:'dstore_3        '; b:(0,0,0,0)),      {Сохранение двойного вещественного в локальной переменной 3}
{4B}  (s:'astore_0        '; b:(0,0,0,0)),      {Сохранение объектной ссылки в локальной переменной 0}
{4C}  (s:'astore_1        '; b:(0,0,0,0)),      {Сохранение объектной ссылки в локальной переменной 1}
{4D}  (s:'astore_2        '; b:(0,0,0,0)),      {Сохранение объектной ссылки в локальной переменной 2}
{4E}  (s:'astore_3        '; b:(0,0,0,0)),      {Сохранение объектной ссылки в локальной переменной 3}
{4F}  (s:'iastore        '; b:(0,0,0,0)),      {Сохранение в целочисленном массиве}
{50}  (s:'lastore        '; b:(0,0,0,0)),      {Сохранение в массиве из длинных целых}
{51}  (s:'fastore        '; b:(0,0,0,0)),      {Сохранение в массиве из одинарных вещественных}
{52}  (s:'dastore        '; b:(0,0,0,0)),      {Сохранение в массиве из двойных вещественных}
{53}  (s:'aastore        '; b:(0,0,0,0)),      {Сохранение в массиве из объектных ссылок}
{54}  (s:'bastore        '; b:(0,0,0,0)),      {Сохранение в массиве байтов со знаком}
{55}  (s:'castore        '; b:(0,0,0,0)),      {Сохранение в символьном массиве}
{56}  (s:'sastore        '; b:(0,0,0,0)),      {Сохранение в массиве из коротких целых}
{57}  (s:'pop            '; b:(0,0,0,0)),      {Извлечение слова с вершины стека}
{58}  (s:'pop2            '; b:(0,0,0,0)),      {Извлечение двух слов с вершины стека}
{59}  (s:'dup            '; b:(0,0,0,0)),      {Дублирование слова на вершине стека}
{5A}  (s:'dup_x1          '; b:(0,0,0,0)),      {Дублирование слово на вершине стека
                                                и помещение копии в стек на два слова ниже}
{5B}  (s:'dup_x2          '; b:(0,0,0,0)),      {Дублирование вершины стека и помещение копии на три слова ниже}
{5C}  (s:'dup2            '; b:(0,0,0,0)),      {Дублирование двух слов на вершине стека}
{5D}  (s:'dup2_x1        '; b:(0,0,0,0)),      {Дублирование двух слов на вершине стека и помещение копий на два слова ниже}
{5E}  (s:'dup2_x2        '; b:(0,0,0,0)),      {Дублирование двух слов на вершине стека и помещение копий на три слова ниже}
{5F}  (s:'swap            '; b:(0,0,0,0)),      {Обмен двух слов на вершине стека}
{60}  (s:'iadd            '; b:(0,0,0,0)),      {Сложение целых}
{61}  (s:'ladd            '; b:(0,0,0,0)),      {Сложение длинных целых}
{62}  (s:'fadd            '; b:(0,0,0,0)),      {Сложение одинарных вещественных}
{63}  (s:'dadd            '; b:(0,0,0,0)),      {Сложение двойных вещественных}
{64}  (s:'isub            '; b:(0,0,0,0)),      {Вычитание целых}
{65}  (s:'lsub            '; b:(0,0,0,0)),      {Вычитание длинных целых}
{66}  (s:'fsub            '; b:(0,0,0,0)),      {Вычитание одинарных вещественных}
{67}  (s:'dsub            '; b:(0,0,0,0)),      {Вычитание двойных вещественных}
{68}  (s:'imul            '; b:(0,0,0,0)),      {Умножение целых}
{69}  (s:'lmul            '; b:(0,0,0,0)),      {Умножение длинных целых}
{6A}  (s:'fmul            '; b:(0,0,0,0)),      {Умножение одинарных вещественных}
{6B}  (s:'dmul            '; b:(0,0,0,0)),      {Умножение двойных вещественных}
{6C}  (s:'idiv            '; b:(0,0,0,0)),      {Деление целых}
{6D}  (s:'ldiv            '; b:(0,0,0,0)),      {Деление длинных целых}
{6E}  (s:'fdiv            '; b:(0,0,0,0)),      {Деление одинарных вещественных}
{6F}  (s:'ddiv            '; b:(0,0,0,0)),      {Деление двойных вещественных}
{70}  (s:'irem            '; b:(0,0,0,0)),      {Остаток от деления целых}
{71}  (s:'lrem            '; b:(0,0,0,0)),      {Остаток от деления длинных целых}
{72}  (s:'frem            '; b:(0,0,0,0)),      {Остаток от деления одинарных вещественных}
{73}  (s:'drem            '; b:(0,0,0,0)),      {Остаток от деления двойных вещественных}
{74}  (s:'ineg            '; b:(0,0,0,0)),      {Отрицание целого}
{75}  (s:'leg            '; b:(0,0,0,0)),      {Отрицание длинного целого}
{76}  (s:'fneg            '; b:(0,0,0,0)),      {Отрицание одинарного вещественного}
{77}  (s:'dneg            '; b:(0,0,0,0)),      {Отрицание двойного вещественного числа}
{78}  (s:'ishl            '; b:(0,0,0,0)),      {Сдвиг целого влево}
{79}  (s:'lshl            '; b:(0,0,0,0)),      {Сдвиг длинного целого влево}
{7A}  (s:'ishr            '; b:(0,0,0,0)),      {Арифметический сдвиг целого вправо}
{7B}  (s:'lshr            '; b:(0,0,0,0)),      {Арифметический сдвиг длинного целого вправо}
{7C}  (s:'iushr          '; b:(0,0,0,0)),      {Логический сдвиг целого вправо}
{7D}  (s:'lushr          '; b:(0,0,0,0)),      {Логический сдвиг длинного целого вправо}
{7E}  (s:'iand            '; b:(0,0,0,0)),      {Логическое И с операндами целого типа}
{7F}  (s:'land            '; b:(0,0,0,0)),      {Логическое И с операндами длинного целого типа}
{80}  (s:'ior            '; b:(0,0,0,0)),      {Логическое ИЛИ с целочисленными операндами}
{81}  (s:'lor            '; b:(0,0,0,0)),      {Логическое ИЛИ с операндами длинного целого типа}
{82}  (s:'ixor            '; b:(0,0,0,0)),      {Исключающее ИЛИ с целочисленными операндами}
{83}  (s:'lxor            '; b:(0,0,0,0)),      {Исключающее ИЛИ с операндами длинного целого типа}
{84}  (s:'iinc            '; b:(ac,ns,0,0)),    {2,Увеличение локальной переменной на константу}
{85}  (s:'i2l            '; b:(0,0,0,0)),      {Преобразование целого в длинное целое}
{86}  (s:'i2f            '; b:(0,0,0,0)),      {Целое в вещественное}
{87}  (s:'i2d            '; b:(0,0,0,0)),      {Целое в двойное вещественное}
{88}  (s:'l2i            '; b:(0,0,0,0)),      {Длинное целое в целое}
{89}  (s:'l2f            '; b:(0,0,0,0)),      {Длинное целое в вещественное}
{8A}  (s:'l2d            '; b:(0,0,0,0)),      {Длинное целое в двойное вещественное}
{8B}  (s:'f2i            '; b:(0,0,0,0)),      {Вещественное в целое}
{8C}  (s:'f2l            '; b:(0,0,0,0)),      {Вещественное в длинное целое}
{8D}  (s:'f2d            '; b:(0,0,0,0)),      {Вещественное в двойное вещественное}
{8E}  (s:'d2i            '; b:(0,0,0,0)),      {Двойное вещественное в целое}
{8F}  (s:'d2l            '; b:(0,0,0,0)),      {Двойное вещественное в длинное целое}
{90}  (s:'d2f            '; b:(0,0,0,0)),      {Двойное вещественное в вещественное}
{91}  (s:'int2byte        '; b:(0,0,0,0)),      {Целое в знаковый байт}
{92}  (s:'int2char        '; b:(0,0,0,0)),      {Целое в символ}
{93}  (s:'int2short      '; b:(0,0,0,0)),      {Целое в короткое}
{94}  (s:'lcmp            '; b:(0,0,0,0)),      {Сравнение длинных целых}
{95}  (s:'fcmpl          '; b:(0,0,0,0)),      {Сравнение вещественных одинарной точности (-1 при NaN)}
{96}  (s:'fcmpg          '; b:(0,0,0,0)),      {Сравнение вещественных одинарной точности (1 при NaN)}
{97}  (s:'dcmpl          '; b:(0,0,0,0)),      {Сравнение вещественных двойной точности(-1 при NaN)}
{98}  (s:'dcmpg          '; b:(0,0,0,0)),      {Сравнение вещественных двойной точности(1 при NaN)}
{99}  (s:'ifeq            '; b:(of2,0,0,0)),    {2,Переход, если равно 0}
{9A}  (s:'ifne            '; b:(of2,0,0,0)),    {2,Переход, если не равно 0}
{9B}  (s:'iflt            '; b:(of2,0,0,0)),    {2,Переход, если меньше 0}
{9C}  (s:'ifge            '; b:(of2,0,0,0)),    {2,Переход, если больше или равно 0}
{9D}  (s:'ifgt            '; b:(of2,0,0,0)),    {2,Переход, если больше 0}
{9E}  (s:'ifle            '; b:(of2,0,0,0)),    {2,Переход, если меньше или равно 0}
{9F}  (s:'if_icmpeq      '; b:(of2,0,0,0)),    {2,Переход, если целые равны}
{A0}  (s:'if_icmpne      '; b:(of2,0,0,0)),    {2,Переход, если целые не равны}
{A1}  (s:'if_icmplt      '; b:(of2,0,0,0)),    {2,Переход, если целое меньше 0}
{A2}  (s:'if_icmpge      '; b:(of2,0,0,0)),    {2,Переход, если целое больше или равно}
{A3}  (s:'if_icmpgt      '; b:(of2,0,0,0)),    {2,Переход, если целое больше 0}
{A4}  (s:'if_icmple      '; b:(of2,0,0,0)),    {2,Переход, если целое меньше или равно}
{A5}  (s:'if_acmpeq      '; b:(of2,0,0,0)),    {2,Переход, если ссылки на объект равны}
{A6}  (s:'if_acmpne      '; b:(of2,0,0,0)),    {2,Переход, если ссылки на объект не равны}
{A7}  (s:'goto            '; b:(of2,0,0,0)),    {2,Переход на}
{A8}  (s:'jsr            '; b:(ofp2,0,0,0)),  {2,Переход на подпрограмму}
{A9}  (s:'ret            '; b:(rtb,0,0,0)),    {1,Возврат из подпрограммы}
{AA}  (s:'tableswitch    '; b:(0,0,0,0)),      {Доступ к таблице перехода по индексу и переход}
{AB}  (s:'lookupswitch    '; b:(0,0,0,0)),      {Доступ к таблице перехода по сравнению с ключом и переход}
{AC}  (s:'ireturn        '; b:(0,0,0,0)),      {Возврат целого значения функции}
{AD}  (s:'lreturn        '; b:(0,0,0,0)),      {Возврат длинного целого значения функции}
{AE}  (s:'freturn        '; b:(0,0,0,0)),      {Возврат одинарного вещественного значения функции}
{AF}  (s:'dreturn        '; b:(0,0,0,0)),      {Возврат двойного вещественного значения функции}
{B0}  (s:'areturn        '; b:(0,0,0,0)),      {Возврат объектной ссылки из функции}
{B1}  (s:'return          '; b:(0,0,0,0)),      {Возврат(опустошающий) из процедуры}
{B2}  (s:'getstatic      '; b:(cp,0,0,0)),    {2,Получение статического поля класса}
{B3}  (s:'putstatic      '; b:(cp,0,0,0)),    {2,Установка статического поля в классе}
{B4}  (s:'getfield        '; b:(cp,0,0,0)),    {2,Перенос поля из объекта}
{B5}  (s:'putfield        '; b:(cp,0,0,0)),    {2,Установка поля в объекте}
{B6}  (s:'invokevirtual  '; b:(cv,0,0,0)),    {2,Вызывает метод экземпляра, основываясь на типе времени выполнения}
{B7}  (s:'invokenonvirtual'; b:(cv,0,0,0)),    {2,Вызывает метод экземпляра, основываясь на не виртуальном типе}
{B8}  (s:'invokestatic    '; b:(cv,0,0,0)),    {2,Вызов метода класса (статического метода)}
{B9}  (s:'invokeinterface '; b:(cv,nb,nb,0)),  {4,Вызывает метод интерфейса}
{BA}  (s:'                '; b:(0,0,0,0)),      {}
{BB}  (s:'new            '; b:(cn,0,0,0)),    {2,Создает новый объект}
{BC}  (s:'newarray        '; b:(nb,0,0,0)),    {1,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}
{BD}  (s:'anewarray      '; b:(ck,0,0,0)),    {2,Объявление нового массива из ссылок на объекты}
{BE}  (s:'arraylength    '; b:(0,0,0,0)),      {Возвращает длину массива}
{BF}  (s:'athrow          '; b:(0,0,0,0)),      {Генерация обработки или ошибки}
{C0}  (s:'checkcast      '; b:(cs,0,0,0)),    {2,Проверяет, что объект имеет данный тип}
{C1}  (s:'instanceof      '; b:(ck,0,0,0)),    {2,Определяет, имеет ли объект данный тип}
{C2}  (s:'monitorenter    '; b:(0,0,0,0)),      {Вход в контролируемую область кода}
{C3}  (s:'monitorexit    '; b:(0,0,0,0)),      {Выход из контролируемой области кода}
{C4}  (s:'wide            '; b:(nw,0,0,0)),    {1,Расширенный индекс для доступа к локальным переменным для
                                                команд загрузки, сохранения и приращени}
{C5}  (s:'multianewarray  '; b:(cn,nb,0,0)),    {3,Размещение нового многомерного массива}
{C6}  (s:'ifnull          '; b:(of2,0,0,0)),    {2,Переход, если пустой указатель}
{C7}  (s:'ifnonnull      '; b:(of2,0,0,0)),    {2,Переход, если не пустой указатель}
{C8}  (s:'goto_w          '; b:(of4,0,0,0)),    {4,Переход на (расширенный индекс)}
{C9}  (s:'jsr_w          '; b:(ofp4,0,0,0)),  {4,Переход на подпрограмму (расширенный индекс)}
{CA}  (s:'breakpoint      '; b:(0,0,0,0)),      {Остановка и передача контроля обработчику прерываний}
{CB}  (s:'                '; b:(0,0,0,0)),      {}
{CC}  (s:'                '; b:(0,0,0,0)),      {}
{CD}  (s:'                '; b:(0,0,0,0)),      {}
{CE}  (s:'                '; b:(0,0,0,0)),      {}
{CF}  (s:'                '; b:(0,0,0,0)),      {}
{D0}  (s:'                '; b:(0,0,0,0)),      {}
{D1}  (s:'ret_w          '; b:(rtw,0,0,0)),    {2,Возврат из подпрограммы (расширенный индекс)}
{D2}  (s:'                '; b:(0,0,0,0)),      {}
{D3}  (s:'                '; b:(0,0,0,0)),      {}
{D4}  (s:'                '; b:(0,0,0,0)),      {}
{D5}  (s:'                '; b:(0,0,0,0)),      {}
{D6}  (s:'                '; b:(0,0,0,0)),      {}
{D7}  (s:'                '; b:(0,0,0,0)),      {}
{D8}  (s:'                '; b:(0,0,0,0)),      {}
{D9}  (s:'                '; b:(0,0,0,0)),      {}
{DA}  (s:'                '; b:(0,0,0,0)),      {}
{DB}  (s:'                '; b:(0,0,0,0)),      {}
{DC}  (s:'                '; b:(0,0,0,0)),      {}
{DD}  (s:'                '; b:(0,0,0,0)),      {}
{DE}  (s:'                '; b:(0,0,0,0)),      {}
{DF}  (s:'                '; b:(0,0,0,0)),      {}
{E0}  (s:'                '; b:(0,0,0,0)),      {}
{E1}  (s:'                '; b:(0,0,0,0)),      {}
{E2}  (s:'                '; b:(0,0,0,0)),      {}
{E3}  (s:'                '; b:(0,0,0,0)),      {}
{E4}  (s:'                '; b:(0,0,0,0)),      {}
{E5}  (s:'                '; b:(0,0,0,0)),      {}
{E6}  (s:'                '; b:(0,0,0,0)),      {}
{E7}  (s:'                '; b:(0,0,0,0)),      {}
{E8}  (s:'                '; b:(0,0,0,0)),      {}
{E9}  (s:'                '; b:(0,0,0,0)),      {}
{EA}  (s:'                '; b:(0,0,0,0)),      {}
{EB}  (s:'                '; b:(0,0,0,0)),      {}
{EC}  (s:'                '; b:(0,0,0,0)),      {}
{ED}  (s:'                '; b:(0,0,0,0)),      {}
{EE}  (s:'                '; b:(0,0,0,0)),      {}
{EF}  (s:'                '; b:(0,0,0,0)),      {}
{F0}  (s:'                '; b:(0,0,0,0)),      {}
{F1}  (s:'                '; b:(0,0,0,0)),      {}
{F2}  (s:'                '; b:(0,0,0,0)),      {}
{F3}  (s:'                '; b:(0,0,0,0)),      {}
{F4}  (s:'                '; b:(0,0,0,0)),      {}
{F5}  (s:'                '; b:(0,0,0,0)),      {}
{F6}  (s:'                '; b:(0,0,0,0)),      {}
{F7}  (s:'                '; b:(0,0,0,0)),      {}
{F8}  (s:'                '; b:(0,0,0,0)),      {}
{F9}  (s:'                '; b:(0,0,0,0)),      {}
{FA}  (s:'                '; b:(0,0,0,0)),      {}
{FB}  (s:'                '; b:(0,0,0,0)),      {}
{FC}  (s:'                '; b:(0,0,0,0)),      {}
{FD}  (s:'                '; b:(0,0,0,0)),      {}
{FE}  (s:'                '; b:(0,0,0,0)),      {}
{FF}  (s:'                '; b:(0,0,0,0)));    {}


  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 hex2(w : word) : string;
begin
  hex2 := hex(hi(w))+hex(lo(w));
end;

function hex4(l : longInt) : string;
var        {longInt to hexLongInt}
  b : array[0..3] of byte absolute l;
Begin
  hex4 := hex(b[3])+hex(b[2])+hex(b[1])+hex(b[0]);
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_InterfaceMethodref:
          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;
  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_InterfaceMethodref:
      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 disasm;
var
  op,k : byte;
begin
  get(p,1);
  op:=byte(p^);
  inc(p);
  write(hex(op),' '+jbc[op].s+' ');
  for k:=0 to 3 do
  case jbc[op].b[k] of
    0: begin end;
    nb:  {1байт целое беззнаковое}
      begin
        write(hex(byte(get(p,1)^)),' ');
        inc(p);
      end;
    ns:  {1байт целое знаковое}
      begin
        write(hex(byte(get(p,1)^)),' ');
        inc(p);
      end;
    nw:  {2байта целое беззнаковое}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ni:  {2байта целое знаковое}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cb:  {1байт индекс в константном пуле }
      begin
        write(hex(byte(get(p,2)^)),' ');
        inc(p,1);{}
{      write(hexw(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);{}
      end;
    cw:  {2байт индекс в константном пуле 2-х байтовой константы}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cl:  {2байт индекс в константном пуле 2-х словной константы}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cp:  {2байт индекс в константном пуле Получение статического поля класса  Элементом константного пула
          будет поле ссылки на статическое поле класса - полями шириной как 64-бита так и 32-бита}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cv:  {2байт индекс в константном пуле текущего класса - сигнатура метода}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cn:  {2байт - конструирование индекса в константном пуле}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ck:  {2байт  индекс на класс}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cs:  {2байт  индекс на строку}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lii:  {загрузка целого из локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lil:  {загрузка длинного целого из локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lif:  {загрузка вещественного одинарной точности из локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lid:  {загрузка вещественного двойной точности из локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lio:  {загрузка объектной ссылки из локальной переменной}
      begin
{      write(hex(byte(get(p,1)^)),' ');
        inc(p,1);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    sii:  {сохранение целого значения в локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    sil:  {сохранение длинного целого в локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    sif:  {Сохранение вещественного одинарной точности в локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);{}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    sid:  {Сохранение двойного вещественного в локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    sio:  {Сохранение объектной ссылки в локальной переменной}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ac:  {Увеличение локальной переменной на константу}
      begin
{        write(hex(byte(get(p,1)^)),' ');
        inc(p);}
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    of2:  {16-битное знаковое смещение}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    of4:  {32-битное знаковое смещение}
      begin
        write(hex4(longInt(swap4(get(p,4),0)^)),' ');
        inc(p,4);
      end;
    ofp2: {16-битное знаковое смещение Переход на подпрограмму}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ofp4: {32-битное знаковое смещение Переход на подпрограмму}
      begin
        write(hex4(longInt(swap4(get(p,4),0)^)),' ');
        inc(p,4);
      end;
    rtb:  {8-битный адрес Возврат из подпрограммы - адрес возврата}
      begin
        write(hex(word(get(p,1)^)),' ');
        inc(p);
      end;
    rtw:  {16-битный адрес возврата}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    else writeln('Error: str:[', op, ',', k, ']=', jbc[op].b[k]);
  end;
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_InterfaceMethodref:
      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(swap4(p,0)^));
        inc(i);
      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:3,']','=');
        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;
var
  offs,start :^byte;
begin
  writeln(hex4(rc), 'h  genericAttribute_info');
  p:=get(p,sizeof(pGenericAttribute_info^));
  pGenericAttribute_info:=swap2(swap4(p,0),0);
  s := getConstStr(pGenericAttribute_info^.attribute_name-1);
  writeln('      attribute_name:  ',pGenericAttribute_info^.attribute_name,' -> ',s);
  writeln('      attribute_length:',pGenericAttribute_info ^.attribute_length);
  if s='Code' then
  begin
    writeln(hex4(rc), 'h  Code:');
    p := get(p,sizeof(pCode_attribute^));
    pCode_attribute := swap2(swap2(swap4(p,0),0),0);
    writeln(hex4(rc-sizeof(pCode_attribute^.max_stack)),
    'h  max_stack:  ', pCode_attribute^.max_stack);
    writeln(hex4(rc-sizeof(pCode_attribute^.max_locals)),
    'h  max_locals: ', pCode_attribute^.max_locals);
    writeln(hex4(rc-sizeof(pCode_attribute^.code_length)),
    'h  code_length:', pCode_attribute^.code_length);
    start := @p^;
    offs  := @p^;
    inc(longInt(offs), pCode_attribute^.code_length);
    writeln('_______DISASSEMBLE-START_______');
    while (longInt(p) < longInt(offs)) do
    begin
      write(hex4(longInt(p)-longInt(start)),'h  ');
      disasm;
      writeln;
    end;
    writeln('________DISASSEMBLE-END________');
(*  writeln;
    n := 0;
    while n < pCode_attribute^.code_length do
    begin
      write(hexw(n),'h'#9, hex(byte(p^)),' ');
      op:=byte(get(p,1)^);
      inc(p);
      case byte(p^) of
{1}    18:
          begin
            get(p,1); p1:=byte(p^); write(hex(byte(p^)),' ');
            write(TAB2,ByteCode[op],' ',hex(p1),'h');
            inc(n);
          end;
{2}    17,19,20,132,153..168,178..184,187,189,192,193,198,199,209:
          begin
            get(p,1); p1:=byte(p^); write(hex(byte(p^)),' ');
            get(p,1); p2:=byte(p^); write(hex(byte(p^)),' ');
            write(TAB,ByteCode[op],' ',hex(p1),hex(p2),'h');
            inc(n,2);
          end;
{3}    197:
          begin
            inc(n,3);
          end;
{4}    185,200,201:
          begin
            inc(n,4);
          end;
{10}    171:
          begin
          end;
{14}    170:
          begin
          end;
        else write('  ',ByteCode[byte(p^)]);
      end;
      writeln;
      inc(n);
    end;
    {for n := 0 to pCode_attribute^.code_length-1 do
    begin
      get(p,1);
      write(hex(byte(p^)),' ');
      if (n mod 8)=0 then writeln;
    end;{}*)

    writeln;
    p := get(p,sizeof(pexception_table_length^));
    pexception_table_length:=swap2(p,0);
    writeln(hex4(rc-sizeof(pexception_table_length^)),'h  pexception_table [',pexception_table_length^,']=');
    for n := 0 to pexception_table_length^-1 do
    begin
      writeln(hex4(rc), 'h  exception_table:',i,'_');
      p := get(p,sizeof(pException_table^));
      pException_table := swap2(swap2(swap2(swap2(p,0),0),0),0);
      writeln('    start_pc:  ', pException_table^.start_pc);
      writeln('    end_pc:    ', pException_table^.end_pc);
      writeln('    handler_pc:', pException_table^.handler_pc);
      writeln('    catch_type:', pException_table^.catch_type);
    end;
    p := get(p,sizeof(pattributes_count^));
    pattributes_count :=swap2(p,0);
    writeln('    attributes [',pAttributes_count^,']=');
    for n := 0 to pAttributes_count^-1 do
    begin
      writeln(hex4(rc),'h  attributes_info :',n,'_');
      load_attribute_info;
    end;
  end
  else if s='LocalVariableTable' then
  begin
    writeln(hex4(rc), 'h  LocalVariableTable');
    p := get(p,sizeof(pLocalVariableTable_attribute^));
    pLocalVariableTable_attribute := swap2(swap4(swap2(p,0),0),0);
    writeln(hex4(rc-sizeof(pLocalVariableTable_attribute^.attribute_name_index)),
    '    attribute_name_index:      ', pLocalVariableTable_attribute^.attribute_name_index);
    writeln(hex4(rc-sizeof(pLocalVariableTable_attribute^.attribute_length)),
    '    attribute_length:          ', pLocalVariableTable_attribute^. attribute_length);
    writeln(hex4(rc-sizeof(pLocalVariableTable_attribute^.local_variable_table_length)),
    '    local_variable_table_length:', pLocalVariableTable_attribute^.local_variable_table_length);
    for n := 0 to pLocalVariableTable_attribute^.local_variable_table_length-1 do
    begin
      writeln(hex4(rc),'h  localVariableTable_attribute',i,'_');
      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_pc);
      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
  else if s='LineNumberTable' then
  begin
    writeln(hex4(rc),'h  LineNumberTable [', pGenericAttribute_info^.attribute_length,']=');
    for n := 0 to pGenericAttribute_info^.attribute_length-1 do
    begin
      get(p,1);
      {write(hex(byte(p^)),' ');{}
      inc(p);
    end;
    {p:=get(p,2);
    n:=word(swap2(p,0)^);
    writeln(hex4(rc),'h  line_number_table [',n,']=');
    while n>0 do
    begin
      writeln('    start_pc    :', hexw(word(swap2(get(p,2),0)^)));
      inc(p,2);
      writeln('    line_number :', hexw(word(swap2(get(p,2),0)^)));
      inc(p,2);
      dec(n);
    end;}
  end
  {if s='SourceFile' then
  begin
  end{}
  else {don't know... skip atributes}

  begin
    writeln(hex4(rc),'h  ANY_BLOCK [', pGenericAttribute_info^.attribute_length,']=');
    for n := 0 to pGenericAttribute_info^.attribute_length-1 do
    begin
      get(p,1);
      write(' ',hex(byte(p^)));
      if ((n+1) mod 16)=0 then writeln;
      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^.attributes_count);
  for j := 0 to pfield_info^.attributes_count-1 do
  begin
    writeln(hex4(rc),'h  attributes_info :',j,'_');
    load_attribute_info;
  end;
end;


procedure method_info;
begin
  p := get(p,sizeof(pmethod_info^));
  pmethod_info := swap2(swap2(swap2(swap2(p,0),0),0),0);
  s := getConstStr(pmethod_info^.name_index-1);
  writeln('      access_flags:    ',pmethod_info^.access_flags );
  writeln('      name_index:    [',pmethod_info^.name_index,'] -> ',s);
  writeln('      signature_index: ',pmethod_info^.signature_index);
  writeln('      attributes_count:',pmethod_info^.attributes_count);
  for j := 0 to pmethod_info^.attributes_count-1 do
  begin
    writeln(hex4(rc),'h  attributes_info :',j,'_');
    load_attribute_info;
  end;
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_version),n);
  blockWrite(f,cf.major_version,sizeof(cf.major_version),n);{...}
  reset(f,1);
  rc := 0;
  swap4(get(@cf.magic,sizeof(cf.magic)),0);
  swap2(get(@cf.minor_version,sizeof(cf.minor_version)),0);
  swap2(get(@cf.major_version,sizeof(cf.major_version)),0);
  swap2(get(@cf.constant_pool_count,sizeof(cf.constant_pool_count)),0);
  p := @cf.cp_info^;
  i := 1;
  while i < cf.constant_pool_count do
  begin
    write(hex4(rc-1),'h ',i:3,' ');
    load_const;
    inc(i);
  end;
  writeln;
  swap2(get(@cf.access_flags,sizeof(cf.access_flags)),0);
  writeln(hex4(rc-sizeof(cf.access_flags)),'h  access_flags:',cf.access_flags);
  swap2(get(@cf.this_class,sizeof(cf.this_class)),0);
  writeln(hex4(rc-sizeof(cf.this_class)),  'h  this_class:  ',cf.this_class);
  swap2(get(@cf.super_class,sizeof(cf.super_class)),0);
  writeln(hex4(rc-sizeof(cf.super_class)), 'h  super_class: ',cf.super_class);
  writeln;
  swap2(get(@cf.interfaces_count,sizeof(cf.interfaces_count)),0);
  writeln(hex4(rc-sizeof(cf.interfaces_count)),'h  INTERFACES_INFO [',cf.interfaces_count,']=');
  p := @cf.interfaces^;
  for i := 0 to cf.interfaces_count-1 do
  begin
    writeln(hex4(rc), 'h  interfaces_info :',i,'___');
    load_interfaces;
  end;
  writeln;
  swap2(get(@cf.fields_count,sizeof(cf.fields_count) ),0);
  writeln(hex4(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(hex4(rc), 'h  field_info :',i,'___');
    load_field_info;
  end;
  writeln;
  swap2(get(@cf.methods_count,sizeof(cf.methods_count)),0);
  writeln(hex4(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(hex4(rc),'h  method_info :',i,'___');
    method_info;
  end;
  writeln;
  swap2(get(@cf.attributes_count,sizeof(cf.attributes_count)),0);
  writeln(hex4(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
    writeln(hex4(rc),'h  attributes_info :',i,'___');
    load_attribute_info;
  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.


satan 29.09.2008 08:21

Re: создание MIDletPascal compiler'a
 
Гут... Мысль понял... Токма у меня опять в штопор входит...
Надо так, ваще вечером загружу TurboDelphi 2006, оно бесплатное и там помойму с памятью корректнее работает, паетому на ней программы можно и продовать и раздавать... Да и синхронность будет!

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

Теперь пример уже синтаксического анализатора, который разбирает строки вида
N +/- ... Где N - цифра, тоесть типа
1+2-3+1-6 или 3+3+5+6-4 ну и т.д... Начнем с азов...

Код:

{$APPTYPE CONSOLE}

const TAB = ^I;
var Look: char;

procedure GetChar; begin Read(Look); end;
procedure Error(s: string); begin WriteLn; WriteLn(^G, 'Error: ', s, '.'); end;
procedure Abort(s: string); begin Error(s); Halt; end;
procedure Expected(s: string); begin Abort(s + ' Expected'); end;
procedure Match(x: char); begin if Look = x then GetChar else Expected('''' + x + ''''); end;
function IsAlpha(c: char): boolean; begin IsAlpha := upcase(c) in ['A'..'Z']; end;
function IsDigit(c: char): boolean; begin IsDigit := c in ['0'..'9']; end;

function GetName: char;
begin
  if not IsAlpha(Look) then Expected('Name');
  GetName := UpCase(Look);
  GetChar;
end;

function GetNum: char;
begin
  if not IsDigit(Look) then Expected('Integer');
  GetNum := Look;
  GetChar;
end;

procedure Emit(s: string); begin Write(TAB, s); end;
procedure EmitLn(s: string); begin Emit(s); WriteLn; end;

//--------------------------S analizator-----------------------------

procedure Term;
begin
  EmitLn('bipush ' + GetNum);
end;

procedure Add;
begin
  Match('+');
  Term;
  EmitLn('iadd');
end;

procedure Sub;
begin
  Match('-');
  Term;
  EmitLn('isub');
  EmitLn('ineg');
end;

procedure Expression;
begin
  Term;
  while Look in ['+', '-'] do begin
      case Look of
      '+': Add;
      '-': Sub;
      else Expected('Addop');
      end;
  end;
end;

//------------------------------------------------------------------

procedure Init;
begin
  GetChar;
end;

begin
  Init;
  Expression;
end.

вобчем сам анализатор пока из 4 фукций

procedure Term;
procedure Add;
procedure Sub;
procedure Expression;

И выдает асм листинг формата JVM
вот пример разбора строки 1+2-3+4-5+6
Код:

        bipush 1
        bipush 2
        iadd
        bipush 3
        isub
        ineg
        bipush 4
        iadd
        bipush 5
        isub
        ineg
        bipush 6
        iadd

В принципе немного отличаецо от Java классики, но ето от того что там используетца польская запись, кстати хто заинтересуеца АЛГОРИТМ ДЕКСТРА для перевода текстовой строки в обратную польскую запись.

satan 29.09.2008 11:12

Re: создание MIDletPascal compiler'a
 
abcdef ну нифига у тя буйсво мысли... Гы... нафиг такие замуты, Java asm не работает напрямую с переменными, оно работает с адресами и стеком.
Смори, я разбил на диапазоны 1б операции 2б операции и т.д. а все чо не входит естественно без операнда сразу со стеком работает... Паетому немного у тя надо ldc оператор поправить, для него операнд следучий байт, тоесть он однобайтный оператор...
А во смори как из ассемблера токда у меня будет переводица в байт код.
Если ща берём байт код и по нему возвращаем оператор
Прим:
ldc - код 18 или байткод $12 то встретив в коде этот байт мы просто возвращаем его оператор
ByteCode[$12] = ldc
а кокда мы будем конвертить из ассемблера, то так же будем вычислять опкод, токма поиском в массиве по значению "ldc" который нам вернет $12 - номер в массиве, ну тоесть уже готовый асм - дизасм есть...

abcdef 29.09.2008 19:49

Ответ: создание MIDletPascal compiler'a
 
все нормуль! мой массив не просто так делался, будем использовать его в компиляторе, он нужен для проверки параметров команды, и.д., а так прийдется большой case писать...
а здесь задал условия в массиве, и все...


ввиду складывающихся сложных взаимосвязей между объектами
предлагаю разделить Pascal-копилятор на две независимые части:
одна из них генерирует текстовый файл с byte-code листингом,
другая собирает class-файл на основе полученного файла.

1. это позволить упростить компилятор, сделает его менее привязанным к структуре формирования java byte-code и внутреннего представления class-файлов.
2. стадия сборки будет построенна более оптимально и наглядно
3. в промежутке между стадиями компиляции можно ознакомиться, или вручную подредактировать байт-код

satan 29.09.2008 20:39

Re: создание MIDletPascal compiler'a
 
А ну да... Гы...

А если разбивать, потом не возникнет путанки со всякими там USES???
Кстать, кокда буим парсить, так и так все залетит в таблицы (типа переменных, классов, функций и т.д..) иль ты чо придумал хитрае?

abcdef 29.09.2008 23:18

Ответ: создание 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 будет только для блока массива констант

satan 30.09.2008 01:22

Re: создание MIDletPascal compiler'a
 
Мля... полна жпа!!!!!!!!!

Пошол в сортир, втыкаю в распечатаный код, прогоняю помалень, вкуриваю...
И тут... Асенило...
Ептель, ты мутишь не токма дизассемблер, но и декомпилер в одном флаконе,
и как тока прогоняю тему все становица на свои места!
Ё... Ты так в следучий раз не шути, луче сразу колись шо ишо задумал, гы...
Если ишо и деобфускатор, ваще попец полный!!!
Ну да ладно, хоть ща догнал тему.

Вопрос на засыпку:
Скока ишо народу понимает суть дела, и ваще хто ишо тута тусу тусуит???

__________________________________________________ _____________________
satan, призываю общаться на нормальном литературном русском языке и не флудить!

abcdef 30.09.2008 19:20

Ответ: создание MIDletPascal compiler'a
 
на данный момент главное - это распознать все byte-code коменды и их особенности, потому что ассемблер должен понимать обрабатывать их все. Но для компилятора языка паскаль хватит не более 30-ти штук..

что-то затянулась у нас стадия разбора команд. Участие в экспериментах пока принимать не могу (попросту нет времени). Когда все будет готово ассемблер можно будет создать за 2-а вечера.

Насчет профилировщика ты правильно понял satan. Но сейчас нужно получить полностью разбор всех java-команд..
желаю удачи - у тебя хороший багаж знаний!

satan 30.09.2008 23:04

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
Ну и тд. Тп.

Компиляцию я показывал сверху, проводица она рекурсией причом очень простенькой

abcdef 01.10.2008 20:12

Ответ: создание 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
  ....
  rtw  = 29; {16-битный адрес возврата}
  wide = 30; {расширить следующую команду}
  jbc : array....

{C4}  (s:'wide            '; b:(wide,0,0,0)),  {1,Расширенный индекс для доступа к локальным переменным для команд загрузки, сохранения и приращени}
....

procedure disasm;
var
  op,k : byte;
begin
  get(p,1);
  op:=byte(p^);
  inc(p);
  write(hex(op),' '+jbc[op].s+' ');
  for k:=0 to 3 do
  case jbc[op].b[k] of
    0: begin end;
    nb:  {1байт целое беззнаковое}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    ns:  {1байт целое знаковое}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    nw:  {2байта целое беззнаковое}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ni:  {2байта целое знаковое}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cb:  {1байт индекс в константном пуле }
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p,1);
      end;
    cw:  {2байт индекс в константном пуле 2-х байтовой константы}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cl:  {2байт индекс в константном пуле 2-х словной константы}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cp:  {2байт индекс в константном пуле Получение статического поля класса  Элементом константного пула
          будет поле ссылки на статическое поле класса - полями шириной как 64-бита так и 32-бита}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cv:  {2байт индекс в константном пуле текущего класса - сигнатура метода}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cn:  {2байт - конструирование индекса в константном пуле}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ck:  {2байт  индекс на класс}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    cs:  {2байт  индекс на строку}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    lii:  {1байт загрузка целого из локальной переменной}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p,1);
      end;
    lil:  {загрузка длинного целого из локальной переменной}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    lif:  {загрузка вещественного одинарной точности из локальной переменной}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    lid:  {загрузка вещественного двойной точности из локальной переменной}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    lio:  {загрузка объектной ссылки из локальной переменной}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    sii:  { сохранение целого значения в локальной переменной}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p,1);
      end;
    sil:  {сохранение длинного целого в локальной переменной}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    sif:  {Сохранение вещественного одинарной точности в локальной переменной}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    sid:  {Сохранение двойного вещественного в локальной переменной}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    sio:  {Сохранение объектной ссылки в локальной переменной}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    ac:  {Увеличение локальной переменной на константу}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p,1);
      end;
    of2:  {16-битное знаковое смещение}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    of4:  {32-битное знаковое смещение}
      begin
        write(hex4(longInt(swap4(get(p,4),0)^)),' ');
        inc(p,4);
      end;
    ofp2: {16-битное знаковое смещение Переход на подпрограмму}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    ofp4: {32-битное знаковое смещение Переход на подпрограмму}
      begin
        write(hex4(longInt(swap4(get(p,4),0)^)),' ');
        inc(p,4);
      end;
    rtb:  {8-битный адрес Возврат из подпрограммы - адрес возврата}
      begin
        get(p,1);
        write(hex(byte(p^)),' ');
        inc(p);
      end;
    rtw:  {16-битный адрес возврата}
      begin
        write(hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    wide:
      begin
        write(' _ ');
        disasm;
        write(' _ ', hex2(word(swap2(get(p,2),0)^)),' ');
        inc(p,2);
      end;
    else writeln('Error: str:[', op, ',', k, ']=', jbc[op].b[k]);
  end;
end;
.....

procedure load_attribute_info;
var
  offs,start :^byte;
  n : integer;
begin
.....



Часовой пояс GMT +4, время: 03:52.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot