MEMORY EDITOR
В ZX-РЕВЮ № 1 за этот год мы опубликовали программу MEMORY EDITOR Александра Гмарь. От себя мы предлагали читателям подумать над тем, как обеспечить программе релоцируемость - возможность загружаться и стартовать с любого адреса. Мы получили два письма на эту тему, которые приводим. Вначале - письмо Марьина Сергея Борисовича (ст. Ардаши Кировской обл.).
Уважаемый "Инфорком"! Вы просили вариант программы "M.E.", которая могла бы сама настраиваться на работу в конкретных адресах. В этой же статье Вы сами дали ответ на этот вопрос, упомянув пакет MONS-CENS. Предлагаю Вам конкретный вариант того, чтобы это осуществить в кодах.
Все это можно делать с помощью той же программы М.Е. Вначале, загружаем код этой программы, затем запускаем его с адреса 28000 (#6D60). Устанавливаем начальный адрес #6D30 (27952) и набираем следующий дамп:
6D30 |
00 |
00 |
21 |
12 |
03 |
09 |
5E |
23 |
5D |
6D38 |
56 |
23 |
7A |
B3 |
28 |
17 |
EB |
09 |
7E |
6D40 |
D5 |
E5 |
5E |
23 |
56 |
EB |
09 |
11 |
43 |
6D48 |
32 |
6D |
B7 |
ED |
52 |
EB |
E1 |
73 |
89 |
6D50 |
23 |
72 |
E1 |
18 |
E1 |
3E |
C3 |
32 |
5F |
6D58 |
32 |
6D |
21 |
7A |
6E |
22 |
33 |
6D |
2F |
6D60 |
|
|
здесь |
дамп |
из |
РЕВЮ- |
94-1 |
|
|
Это процедура-настройщик моего MONS-4 с небольшими изменениями для конкретной программы. Вот листинг этой процедуры:
6D32 |
211203 |
LD |
HL,#0312 |
6D35 |
09 |
ADD |
HL, BC |
6D36 |
5E |
LD |
E,(HL) |
6D37 |
23 |
INC |
HL |
6D38 |
56 |
LD |
D,(HL) |
6D39 |
23 |
INC |
HL |
6D3A |
7A |
LD |
A, D |
6D3B |
B3 |
OR |
E |
6D3C |
2817 |
JR |
Z,# 6D55 |
6D3E |
EB |
EX |
DE, HL |
6D3F |
09 |
ADD |
HL, BC |
6D40 |
D5 |
PUSH |
DE |
6D41 |
E5 |
PUSH |
HL |
6D42 |
5E |
LD |
E,(HL) |
6D43 |
23 |
INC |
HL |
6D44 |
56 |
LD |
D,(HL) |
6D45 |
EB |
EX |
DE, HL |
6D4 6 |
09 |
ADD |
HL, BC |
6D47 |
11326D |
LD |
DE,#6D32 |
6D4A |
B7 |
OR |
A |
6D4B |
ED52 |
SBC |
HL, DE |
6D4D |
EB |
EX |
DE, HL |
6D4E |
E1 |
POP |
HL |
6D4F |
73 |
LD |
(HL),E |
6D50 |
23 |
INC |
HL |
6D51 |
72 |
LD |
(HL),D |
6D52 |
E1 |
POP |
HL |
6D53 |
18E1 |
JR |
# 6D3 6 |
6D55 |
3EC3 |
LD |
A, #C3 |
6D57 |
32326D |
LD |
(#6D32),A |
6D5A |
217A6E |
LD |
HL,# 6E7A |
6D5D |
22336D |
LD |
(#6D33),HL |
6D60 |
. . . |
|
|
Можно поступить проще - запустить MONS-4, переслать начальный блок кодов по адресу #6D32 и произвести изменения кода в отмеченных местах (подчеркнутых в дампе). Следующий этап - ввод таблицы коррекции абсолютных адресов:
7040 |
46 |
29 |
FF |
00 |
26 |
00 |
29 |
00 |
6D |
7048 |
2C |
00 |
2F |
00 |
4E |
00 |
61 |
00 |
C2 |
7050 |
64 |
00 |
6D |
00 |
7A |
00 |
88 |
00 |
93 |
7058 |
8D |
00 |
B0 |
00 |
B3 |
00 |
C8 |
00 |
80 |
7060 |
E0 |
00 |
E3 |
00 |
EA |
00 |
ED |
00 |
6A |
7068 |
F5 |
00 |
00 |
01 |
04 |
01 |
0B |
01 |
DF |
7070 |
18 |
01 |
27 |
01 |
34 |
01 |
37 |
01 |
8E |
7078 |
3A |
01 |
3E |
01 |
41 |
01 |
44 |
01 |
E9 |
7080 |
56 |
01 |
59 |
01 |
5C |
01 |
60 |
01 |
5F |
7088 |
63 |
01 |
67 |
01 |
6D |
01 |
70 |
01 |
A3 |
7090 |
73 |
01 |
76 |
01 |
A3 |
01 |
AA |
01 |
3A |
7098 |
AF |
01 |
F2 |
01 |
00 |
02 |
04 |
02 |
B3 |
7 0A0 |
14 |
02 |
36 |
02 |
3B |
02 |
47 |
02 |
E4 |
7 0A8 |
4A |
02 |
4D |
02 |
50 |
02 |
54 |
02 |
5B |
70B0 |
16 |
00 |
00 |
00 |
00 |
00 |
00 |
00 |
36 |
Все, код загружен! Можно выходить в BASIC и делать SAVE "M.E." CODE 27954,898.
Получилась программа, которую можно загружать в любую область памяти (кроме, естественно, экрана и других важных областей) и запускать с адреса загрузки.
Таким образом, можно доработать любую программу, для этого требуется произвести коррекцию программы-настройщика и составить таблицу изменяемых настройщиком адресов.
Первая коррекция настройщика (подчеркнуто в дампе): смещение начала таблицы коррекции (в данном случае #0312).
Вторая и третья: адрес загрузки и запуска.
Четвертая: адрес запуска собственно программы (можно было бы подставить #6D60).
Пятая: адрес записи этого адреса запуска.
Кстати, если после запуска этой программы по новому адресу восстановить первые три ячейки (21 12 03), то можно смело сбросить ее на ленту или диск, но уже с того места куда она была загружена. Она будет работать так же.
Это не единственный способ сделать программу перемещаемой. Можно, к примеру, уменьшить таблицу в 2 раза, используя не абсолютное, а относительное смещение. То есть смещение относительно предыдущего корректируемого адреса. Я, правда, пока еще этот способ не "обкатал".
Неплохо было бы автоматизировать процесс составления таблицы коррекции. Вручную слишком утомительная работа, особенно если программа довольно большая. Может быть, у кого-нибудь будут на этот счет какие-либо идеи? Например, воспользоваться таблицей меток монитора-дисассемблера, введя в него новую команду.
Еще одна идея: можно совместить эту программу (М.Е.) с программой на стр.57 и тогда можно будет производить загрузку и выгрузку блока кодов на дисковод. Есть еще идея: прицепить ее к MONS'y в качестве дополнительной команды.
Идей много. Все бы реализовать.
Для тех, кто набирал программу "М.Е." с помощью ассемблера: в 1 номере РЕВЮ в листинге на стр.54 внизу в левой колонке лишняя строчка: 6D8D D1 POP DE.
Уважаемые читатели, исправьте, пожалуйста, в своих журналах эту неточность.
А сейчас предлагаем еще одно письмо на эту тему. Его прислал Мокеичев Анатолий Николаевич из г. Гороховец Владимирской обл.
|
Предлагаю Вашему вниманию доработанную мной программу Memory Editor. Она загружается и стартует с |
любого |
адреса. Вот стартовый блок, обеспечивающий перемещаемость. |
6D05 |
CD5200 |
CALL |
#0052 |
6D08 |
3B |
DEC |
SP |
6D09 |
3B |
DEC |
SP |
6D0A |
E1 |
POP |
HL |
6D0B |
E5 |
PUSH |
HL |
6D0C |
DDE1 |
POP |
IX |
6D0E |
112700 |
LD |
DE,#0027 |
6D11 |
DD19 |
ADD |
IX, DE |
6D13 |
0634 |
LD |
B, #34 |
6D15 |
DD5E00 |
LD |
E,(IX+0) |
6D18 |
1600 |
LD |
D, #00 |
6D1A |
19 |
ADD |
HL, DE |
6D1B |
E5 |
PUSH |
HL |
6D1C |
5E |
LD |
E,(HL) |
6D1D |
23 |
INC |
HL |
6D1E |
56 |
LD |
D,(HL) |
6D1F |
19 |
ADD |
HL, DE |
6D2 0 |
EB |
EX |
DE, HL |
6D21 |
E1 |
POP |
HL |
6D22 |
73 |
LD |
(HL),E |
6D23 |
23 |
INC |
HL |
6D24 |
72 |
LD |
(HL),D |
6D25 |
DD23 |
INC |
IX |
6D27 |
10EC |
DJNZ |
#6D15 |
6D2 9 |
CD1803 |
CALL |
#0318 |
6D2C |
C34C01 |
JP |
#014C |
|
Некоторые комментарии к программе. |
#6D05...#6D28 - программа настройки на адрес загрузки. При выполнении подпрограммы #0052 (которая содержит всего одну команду RET) адрес возврата сохраняется на стеке. Благодаря этому обеспечивается привязка к конкретному адресу загрузки. После снятия этого адреса со стека, он суммируется с числами из таблицы смещений, настраивая программу на конкретные адреса загрузки. В командах по адресам #6D29 и #6D2C адреса фиктивные, реальными они станут после отработки процедуры настройки. В результате будем иметь: #6D29...#6D2B -выполнение подпрограммы #7043.#7052, которая делает возможным повторный старт с того же адреса после выхода из программы "Memory Editor", а #6D2C.#6D2E - переход на адрес #6Е7А.
#6D2F...#6D62 - таблица смещений адресов (относительно предыдущего).
В самой же программе изменены только те ячейки памяти, которые должны быть пересчитаны. В исходном варианте (то есть до настройки), в них содержатся значения смещения адреса относительно текущего.
В новом варианте программа загружается с любого адреса. Старт (начальный и последующие) с адреса загрузки. В приводимом дампе для удобства сравнения с исходным вариантом адреса сохранены прежними.
6D00 |
00 |
00 |
00 |
00 |
00 |
CD |
52 |
00 |
8C |
6D08 |
3B |
3B |
E1 |
E5 |
DD |
E1 |
11 |
27 |
A7 |
6D10 |
00 |
DD |
19 |
06 |
34 |
DD |
5E |
00 |
E8 |
6D18 |
16 |
00 |
19 |
E5 |
5E |
23 |
56 |
19 |
89 |
6D2 0 |
EB |
E1 |
73 |
23 |
72 |
DD |
23 |
10 |
71 |
6D2 8 |
EC |
CD |
18 |
03 |
C3 |
4C |
01 |
22 |
9B |
6D30 |
02 |
52 |
12 |
02 |
08 |
0C |
0D |
04 |
2A |
6D38 |
22 |
02 |
14 |
17 |
02 |
06 |
02 |
07 |
05 |
6D40 |
0A |
03 |
06 |
0C |
0E |
0C |
02 |
02 |
EA |
6D48 |
03 |
02 |
02 |
11 |
02 |
02 |
03 |
02 |
D 6 |
6D50 |
03 |
05 |
02 |
02 |
02 |
2C |
06 |
04 |
01 |
6D58 |
42 |
0D |
03 |
0F |
21 |
04 |
0B |
02 |
58 |
6D60 |
02 |
02 |
03 |
1A |
13 |
FE |
FF |
C8 |
C6 |
6D68 |
D7 |
18 |
F8 |
DD |
E5 |
E5 |
D5 |
C5 |
FD |
6D70 |
21 |
3B |
5C |
CB |
AE |
CB |
6E |
28 |
6F |
6D78 |
FC |
3A |
08 |
5C |
F5 |
87 |
87 |
32 |
B4 |
6D80 |
05 |
00 |
11 |
0A |
00 |
21 |
60 |
02 |
90 |
6D88 |
CD |
B5 |
03 |
F1 |
C1 |
D1 |
E1 |
DD |
BB |
6D90 |
E1 |
C9 |
21 |
F8 |
01 |
CD |
02 |
00 |
90 |
6D98 |
41 |
56 |
23 |
5E |
23 |
7A |
CD |
11 |
98 |
6DA0 |
00 |
CB |
27 |
CB |
27 |
CB |
27 |
CB |
AE |
6DA8 |
27 |
4F |
7B |
CD |
04 |
00 |
B1 |
4F |
D7 |
6DB0 |
C9 |
D6 |
30 |
FE |
0A |
D8 |
D6 |
07 |
A9 |
6DB8 |
C9 |
21 |
D1 |
01 |
06 |
04 |
CD |
AB |
63 |
6DC0 |
FF |
FE |
0D |
28 |
25 |
FE |
0C |
28 |
B6 |
6DC8 |
12 |
FE |
30 |
38 |
F1 |
FE |
47 |
30 |
13 |
6DD0 |
ED |
05 |
04 |
28 |
E9 |
77 |
23 |
05 |
E3 |
6DD8 |
D7 |
18 |
E3 |
78 |
FE |
04 |
28 |
DE |
97 |
6DE0 |
2B |
11 |
BF |
01 |
CD |
7D |
FF |
04 |
96 |
6DE8 |
18 |
D4 |
05 |
04 |
20 |
D0 |
18 |
A2 |
F4 |
6DF0 |
F5 |
CB |
2F |
CB |
2F |
CB |
2F |
CB |
0b |
6DF8 |
2F |
CD |
02 |
00 |
F1 |
E6 |
0F |
C6 |
0F |
6E00 |
30 |
FE |
3A |
38 |
02 |
C6 |
07 |
D7 |
B4 |
6E08 |
C9 |
CD |
6B |
0D |
3E |
02 |
CD |
01 |
92 |
6E10 |
16 |
11 |
A5 |
01 |
CD |
4D |
FF |
AF |
13 |
6E18 |
CD |
01 |
16 |
11 |
E9 |
01 |
CD |
43 |
75 |
6E20 |
FF |
3E |
02 |
CD |
01 |
16 |
2A |
62 |
3D |
6E28 |
01 |
0E |
10 |
06 |
08 |
7C |
85 |
5F |
23 |
6E30 |
7C |
CD |
BD |
FF |
7D |
CD |
B9 |
FF |
A5 |
6E38 |
3E |
20 |
D7 |
7E |
CD |
B2 |
FF |
7B |
52 |
6E40 |
86 |
5F |
23 |
10 |
F3 |
3E |
3A |
D7 |
08 |
6E48 |
7B |
CD |
A5 |
FF |
3E |
0D |
D7 |
0D |
D1 |
6E50 |
20 |
D9 |
C9 |
DD |
7E |
00 |
C6 |
05 |
A6 |
6E58 |
32 |
39 |
01 |
DD |
7E |
01 |
CB |
2F |
88 |
6E60 |
DD |
86 |
01 |
C6 |
05 |
32 |
2D |
01 |
5D |
6E68 |
11 |
28 |
01 |
C3 |
F6 |
FE |
F5 |
CD |
89 |
6E70 |
E2 |
FF |
11 |
28 |
01 |
CD |
EC |
FE |
B0 |
6E78 |
F1 |
C9 |
3E |
08 |
32 |
6A |
5C |
CD |
AB |
6E80 |
6B |
0D |
3E |
02 |
CD |
01 |
16 |
11 |
9B |
6E88 |
1D |
01 |
CD |
D7 |
FE |
CD |
2A |
FF |
AC |
6E90 |
ED |
43 |
F7 |
00 |
CD |
73 |
FF |
DD |
41 |
6E98 |
21 |
FC |
00 |
21 |
00 |
00 |
22 |
F6 |
5C |
6EA0 |
00 |
CD |
CB |
FF |
CD |
C5 |
FE |
CD |
02 |
6EA8 |
C5 |
FF |
FE |
48 |
28 |
D1 |
FE |
4E |
65 |
6EB0 |
28 |
22 |
FE |
4B |
28 |
2A |
FE |
58 |
59 |
6EB8 |
28 |
72 |
FE |
0B |
28 |
2D |
FE |
0A |
26 |
6EC0 |
28 |
39 |
FE |
08 |
28 |
45 |
FE |
09 |
09 |
6EC8 |
28 |
51 |
FE |
30 |
38 |
D3 |
FE |
47 |
2D |
6ED0 |
38 |
5E |
18 |
CD |
2A |
B4 |
00 |
01 |
98 |
6ED8 |
80 |
00 |
09 |
22 |
AD |
00 |
18 |
B4 |
6A |
6EE0 |
2A |
A8 |
00 |
01 |
80 |
00 |
B7 |
ED |
45 |
6EE8 |
42 |
18 |
F0 |
DD |
35 |
00 |
DD |
7E |
0D |
6EF0 |
00 |
FE |
FF |
20 |
AC |
DD |
36 |
00 |
3A |
6EF8 |
0F |
18 |
A6 |
DD |
34 |
00 |
DD |
7E |
9F |
6F00 |
00 |
FE |
10 |
20 |
9C |
DD |
36 |
00 |
4C |
6F08 |
00 |
18 |
96 |
DD |
35 |
01 |
DD |
7E |
93 |
6F10 |
01 |
FE |
FF |
20 |
8C |
DD |
36 |
01 |
3D |
6F18 |
0F |
18 |
D0 |
DD |
34 |
01 |
DD |
7E |
EB |
6F20 |
01 |
FE |
10 |
C2 |
7C |
FF |
DD |
36 |
EE |
6F28 |
01 |
00 |
18 |
CF |
CD |
6B |
0D |
C9 |
8D |
6F30 |
F5 |
CD |
7E |
FE |
F5 |
2A |
53 |
00 |
4F |
6F38 |
DD |
7E |
00 |
CB |
27 |
CB |
27 |
CB |
B1 |
6F40 |
27 |
4F |
06 |
00 |
09 |
22 |
49 |
00 |
9F |
6F48 |
DD |
4E |
01 |
CB |
29 |
09 |
DD |
7E |
3B |
6F50 |
01 |
E6 |
01 |
0E |
F0 |
46 |
D1 |
20 |
DC |
6F58 |
0A |
CB |
22 |
CB |
22 |
CB |
22 |
CB |
63 |
6F60 |
22 |
0E |
0F |
78 |
A1 |
B2 |
77 |
CD |
1D |
6F68 |
EA |
FE |
F1 |
D7 |
2A |
22 |
00 |
7C |
4F |
6F70 |
85 |
06 |
08 |
86 |
23 |
10 |
FC |
4F |
76 |
6F78 |
3A |
19 |
00 |
32 |
1C |
00 |
11 |
18 |
B1 |
6F80 |
00 |
CD |
E0 |
FD |
79 |
CD |
69 |
FE |
46 |
6F88 |
18 |
91 |
00 |
00 |
30 |
30 |
30 |
30 |
60 |
6F90 |
80 |
6D |
16 |
05 |
05 |
FF |
00 |
00 |
0b |
6F98 |
16 |
05 |
1D |
FF |
15 |
01 |
8F |
15 |
F8 |
6FA0 |
00 |
FF |
08 |
20 |
08 |
FF |
16 |
0A |
5D |
6FA8 |
03 |
49 |
4E |
50 |
55 |
54 |
20 |
41 |
0B |
6FB0 |
44 |
44 |
52 |
45 |
53 |
53 |
3A |
FF |
1D |
6FB8 |
16 |
00 |
07 |
3C |
20 |
4D |
65 |
6D |
BF |
6FC0 |
6F |
72 |
79 |
20 |
45 |
64 |
69 |
74 |
2F |
6FC8 |
6F |
72 |
20 |
3E |
16 |
01 |
07 |
7F |
13 |
6FD0 |
20 |
65 |
58 |
54 |
72 |
61 |
20 |
53 |
B6 |
6FD8 |
6F |
66 |
74 |
20 |
31 |
39 |
39 |
34 |
87 |
6FE0 |
16 |
03 |
00 |
41 |
44 |
52 |
2E |
20 |
8D |
6FE8 |
30 |
20 |
20 |
31 |
20 |
20 |
32 |
20 |
8A |
6FF0 |
20 |
33 |
20 |
20 |
34 |
20 |
20 |
35 |
9B |
6FF8 |
20 |
20 |
36 |
20 |
20 |
37 |
20 |
53 |
C7 |
7000 |
55 |
4D |
16 |
05 |
00 |
FF |
16 |
00 |
42 |
7008 |
02 |
6B |
65 |
79 |
73 |
3A |
20 |
63 |
F3 |
7010 |
48 |
61 |
6E |
67 |
65 |
20 |
4E |
65 |
36 |
7018 |
78 |
74 |
20 |
62 |
61 |
63 |
4B |
20 |
25 |
7020 |
65 |
58 |
69 |
74 |
16 |
01 |
02 |
63 |
A6 |
7028 |
75 |
72 |
73 |
6F |
72 |
20 |
6B |
65 |
C3 |
7030 |
79 |
73 |
2C |
68 |
65 |
78 |
20 |
6E |
8B |
7038 |
75 |
6D |
62 |
65 |
72 |
28 |
30 |
2D |
48 |
7040 |
46 |
29 |
FF |
E1 |
E5 |
E5 |
D1 |
01 |
9B |
7048 |
27 |
00 |
AF |
ED |
42 |
EB |
0E |
03 |
B9 |
7050 |
ED |
B0 |
C9 |
00 |
00 |
00 |
00 |
00 |
26 |
После набора дампа сохраните программу командой:
SAVE "ME"CODE 27909,846
ОТ РЕДАКЦИИ
Добавим несколько слов. Для тех, кто набирает программу "Memory Editor" заново, можем порекомендовать вариант Анатолия Мокеичева (второй), так как он чуть-чуть короче. В этом варианте интересно то, что до старта отсутствует привязка к конкретным адресам, и это делает исходный листинг программы практически нечитаемым (пример - команды по адресам #6D29 и #6D2C).
Тем, кто уже набрал программу по дампу в 1 номере РЕВЮ-94, можем порекомендовать вариант переделки Сергея Марьина (первый), так как он сводится всего лишь к добавлению небольших новых процедур, а основной блок программы не затрагивается.
* * *