|
Основной форум Сюда все проблемы связанные с программированием. |
27.09.2008, 21:32
|
#46
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: создание 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.$$$
|
(Offline)
|
|
27.09.2008, 21:45
|
#47
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: создание MIDletPascal compiler'a
кстати для прикола: компиляции будет поддаваться файл tmp1.$$$ ... интересно былобы посмотреть на того кто получит исходник подобного вида:
....
n
:=
word
(
swap2
(
p
,
0
)
^
)
;
write
(
'CONSTANT_Utf8-Unicode ['
,
n
,
']='
....
|
(Offline)
|
|
28.09.2008, 04:43
|
#48
|
Нуждающийся
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
|
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;
и получать на выходе уже готовый байт-код
потом перейти к разбору переменных и типов... Это естественно заскочит в таблицы, на основе которых и соберётся заголовок.
|
(Offline)
|
|
28.09.2008, 08:09
|
#49
|
Нуждающийся
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
|
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
ЗЫ...
Я тут разобрал токма двубайтовые операции, просто исходников маловат пока, если есть возможность накидайте простых исходников
с разными выпендрезами, типа исключит. ситуации и т.д... Чоб протестить.
Ассемблирование можно пустить в обратном порядке, тоисть по инструкции просто брать адрес в массиве
и собирать исходный класс.
Последний раз редактировалось satan, 28.09.2008 в 08:42.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо satan за это полезное сообщение:
|
|
28.09.2008, 09:12
|
#50
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: создание MIDletPascal compiler'a
если вы заметили, представляемые исходники, совсем не содержат сложных конструкций, и не используют библиотеки конкретной версии языка... в этом легкость понимания, на каком бы языке не работал читатель. А для полученного продукта - легкость портирования на другие языки.
Хорошая программа в моем понимании - это та, которая выполняет возложенную на нее задачу, написана оптимальными и в тоже время минимальными ресурсами.
А не та, которая спроектирована для использования кучи библиотек, функции которых неоптимально взаимодействуют друг с другом, в виду их разнонаправленности и шаблонности, и большинство возможностей которых ни когда не будут использованы в текущей программе. От этого страдает и скорость работы программы и ее размеры
Синтаксис Pascal отличается тем, что все его конструкции с легкостью можно переделать в синтаксис basic или C. переобразования в обратную сторону несколько сложнее
вот ссылка на последнюю версию <pascals.zip> предлогаемого для модификации компилятора http://www.avhohlov.narod.ru/pascals.zip
|
(Offline)
|
|
28.09.2008, 09:32
|
#51
|
Нуждающийся
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
|
Re: создание MIDletPascal compiler'a
Ну в том и дело, что pascals и context тоже писаны по ред буку, ща я накидаю пост про рек. подъем понятно станет почему луче с низу начинать разбор, и оптимизацию проводить легче...
Кстати Tyni C написано по другому принцпу и читаецо лехше...
Но я не настаиваю...
|
(Offline)
|
|
28.09.2008, 09:38
|
#52
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: создание MIDletPascal compiler'a
молодец satan! держи плюсик!
вечером попробую отправить свою версию..
|
(Offline)
|
|
28.09.2008, 09:54
|
#53
|
Нуждающийся
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
|
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 в 11:41.
|
(Offline)
|
|
28.09.2008, 13:07
|
#54
|
Нуждающийся
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
|
Re: создание MIDletPascal compiler'a
Я хренею... Исходник виртуальной машины
do {
выбор байт кода операции
выполнение действия в зависимости от значения кода
} while (еще нужно выполнять);
|
Мож потом замутим?
|
(Offline)
|
|
29.09.2008, 06:05
|
#55
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: создание 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.
|
(Offline)
|
|
29.09.2008, 08:21
|
#56
|
Нуждающийся
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
|
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 классики, но ето от того что там используетца польская запись, кстати хто заинтересуеца АЛГОРИТМ ДЕКСТРА для перевода текстовой строки в обратную польскую запись.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
29.09.2008, 11:12
|
#57
|
Нуждающийся
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
|
Re: создание MIDletPascal compiler'a
abcdef ну нифига у тя буйсво мысли... Гы... нафиг такие замуты, Java asm не работает напрямую с переменными, оно работает с адресами и стеком.
Смори, я разбил на диапазоны 1б операции 2б операции и т.д. а все чо не входит естественно без операнда сразу со стеком работает... Паетому немного у тя надо ldc оператор поправить, для него операнд следучий байт, тоесть он однобайтный оператор...
А во смори как из ассемблера токда у меня будет переводица в байт код.
Если ща берём байт код и по нему возвращаем оператор
Прим:
ldc - код 18 или байткод $12 то встретив в коде этот байт мы просто возвращаем его оператор
ByteCode[$12] = ldc
а кокда мы будем конвертить из ассемблера, то так же будем вычислять опкод, токма поиском в массиве по значению "ldc" который нам вернет $12 - номер в массиве, ну тоесть уже готовый асм - дизасм есть...
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
29.09.2008, 19:49
|
#58
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: создание MIDletPascal compiler'a
все нормуль! мой массив не просто так делался, будем использовать его в компиляторе, он нужен для проверки параметров команды, и.д., а так прийдется большой case писать...
а здесь задал условия в массиве, и все...
ввиду складывающихся сложных взаимосвязей между объектами
предлагаю разделить Pascal-копилятор на две независимые части:
одна из них генерирует текстовый файл с byte-code листингом,
другая собирает class-файл на основе полученного файла.
1. это позволить упростить компилятор, сделает его менее привязанным к структуре формирования java byte-code и внутреннего представления class-файлов.
2. стадия сборки будет построенна более оптимально и наглядно
3. в промежутке между стадиями компиляции можно ознакомиться, или вручную подредактировать байт-код
|
(Offline)
|
|
29.09.2008, 20:39
|
#59
|
Нуждающийся
Регистрация: 10.02.2007
Сообщений: 99
Написано 18 полезных сообщений (для 28 пользователей)
|
Re: создание MIDletPascal compiler'a
А ну да... Гы...
А если разбивать, потом не возникнет путанки со всякими там USES???
Кстать, кокда буим парсить, так и так все залетит в таблицы (типа переменных, классов, функций и т.д..) иль ты чо придумал хитрае?
Последний раз редактировалось satan, 29.09.2008 в 21:11.
|
(Offline)
|
|
29.09.2008, 23:18
|
#60
|
Знающий
Регистрация: 16.09.2008
Сообщений: 299
Написано 71 полезных сообщений (для 123 пользователей)
|
Ответ: создание 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 будет только для блока массива констант
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 15:52.
|