Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги из ГПНТБ / Система математического обеспечения ЕС ЭВМ

..pdf
Скачиваний:
24
Добавлен:
22.10.2023
Размер:
10.92 Mб
Скачать

занием длины идентификатора, а вслед за ним — сам идентифика­ тор. Необходимо, чтобы макрокоманда SAVE обязательно была первой командой в точке входа.

Первые 4 байта предназначены для команды перехода к коман­ де, следующей за полем идентификатора. Поле идентификатора позволяет очень быстро найти точку входа при анализе дампов (распечаток) памяти, так как идентификатор будет напечатан как содержимое соответствующих байтов памяти.

Все области сохранения образуют

 

список.

Каждая область

связана с предыдущей и последующей

областями. Второе

слово

содержит адрес предыдущей области сохранения

(для самой пер­

вой— 0), третье слово — адрес

последующей

области сохранения

(для самой

последней — 0). Пример

списка трех

областей

сохра­

нения приведен на рис. 20.

 

 

 

 

 

 

 

После возврата управления

 

 

 

 

 

 

• *

из программы ее область со­

 

 

 

 

 

ч»

 

 

 

 

 

 

хранения может быть помечена

 

 

 

 

 

О

 

1

 

 

 

> 1

как не используемая установ­

00

 

00

 

 

 

i> ^J

 

кой в единицу всех битов стар­

 

 

 

 

 

 

 

шего байта

четвертого

слова

 

 

 

 

 

 

 

области

сохранения

(такое

 

 

 

 

 

 

 

средство

существует в макро­

 

 

 

 

 

 

 

команде

RETURN). Это очень

Р ис.

20.

С п и сок

о б л а с т е й с о х р а н е н и я

удобное

средство при анализе

 

 

 

 

 

 

 

дампов, позволяющее установить активную область сохранения и проанализировать содержимое неактивных, но использовавшихся ранее областей сохранения. Так, на рис. 20 — две активные области сохранения и одна (третья) неиспользуемая область.

При передаче управления область сохранения обеспечивается вызывающей программой. Ее адрес передается в регистр 13. Со­ хранение регистров осуществляется в вызываемой программе. Вы­ деление памяти для области сохранения в вызывающей програм­ ме может быть сделано различным способом. Самый простой спо­ соб — это резервирование восемнадцати полных слов с помощью команды DS или DC. Этот способ не может быть использован в реентерабельных программах, так как при каждом повторном вхождении в программу будет использоваться одна и та же об­ ласть сохранения. Ее содержимое ' от первого вхождения буд^1” перекрыто содержимым от второго вхождения.

В реентерабельных программах память для области сохране­ ния необходимо запрашивать макрокомандой GETMAIN. При по­ вторном вхождении в такую программу будет выделен новый уча­ сток памяти для области сохранения, отличный от того, который был выделен при первом вхождении.

Восстановление регистров из области сохранения производится при возврате управления из вызываемой программы. Восстанов­ ление может быть выполнено командой групповой загрузки (LM) либо макрокомандой RETURN. При использовании макрокоманды RETURN необходимо, чтобы регистр 13 содержал адрес области

1.01

сохранения, а регистр 14 — адрес возврата. При выполнении этой макрокоманды в регистр 15 засылается код возврата. Код возвра­

та может быть заслан в регистр

15 как

до

макрокоманды, так и

в самой макрокоманде.

 

 

 

 

Макрокоманда имеет следующий формат:

 

 

[ и м я ] R E T U R N [( р е г и с т р 1 [ ,

реги стр

2 ])]

[, Т] Г, RC = ч и сл о

1

 

 

 

l,R C=(15)

]

Регистры 1 и 2 указывают границы восстановления. Регистры необходимо указывать в том же порядке, как при использовании команды групповой загрузки.

Операнд Т обозначает, что в старший байт четвертого слова области сохранения необходимо занести все единицы, чтобы отме­ тить ее как неиспользуемую.

Последний операнд определяет код возврата, который пред­ ставляет собой число, кратное 4, в диапазоне 0—4095. Нуль яв­ ляется кодом нормального возврата. Предполагается, что вызы­ вающая программа умеет анализировать коды возврата. Первая запись используется, если код возврата определяется в самой мак­ рокоманде. Вторая запись говорит о том, что код возврата ранее был установлен в регистре 15 и его не следует изменять в макро­ расширении. Отсутствие этого операнда указывает на то, что код возврата не устанавливается, а содержимое регистра 15 может быть восстановлено из области сохранения, если это предусмотре­ но в первом операнде. Макрорасширения макрокоманд SAVE и RETURN выполняют все необходимые действия без обращения к программам супервизора.

4.5. ПЕРЕДАЧИ УПРАВЛЕНИЯ

Рассмотрим два типа передач управления с возвратом и без возврата. Передача управления с возвратом предполагает, что после выполнения вызываемой программы управление должно быть передано в вызывающую программу по некоторому адресу

возврата. Передача управления без

возврата

предполагает, что

после

выполнения

вызываемой

программы управление

должно

быть

передано вызывающей программе

более

старшего

уровня

(т. е.

вызывающей

программе

для

вызывающей

программы).

-Рис. 21 иллюстрирует эти положения.

 

управление

без возврата

b

случае б программа 2 передает

программе 3. Возврат из программы

3

должен

быть осуществлен

к программе 1 по адресу возврата, который был передан програм­ ме 2. Прежде чем осуществить передачу управления без возврата, необходимо выполнить подготовительные действия, которые бы обеспечили правильное выполнение возврата управления.

Все перечисленное относится в равной мере как к программам простой структуры, так и к программам динамической структуры. В рассмотренном примере все три программы могут входить в мо­ дуль простой структуры, а передачи управления выполняются

102

Программа f

Программа 2 ‘

Программа 3/

а

П рогра м м а 1

П рограмма 2

Программа 3

б

Р и с . 21 . П е р е д а ч и уп р а в л е н и я с в о зв р а т о м и б е з в о з ­

в р а т а ( с и м в о л о м X п о м еч ен а д р е с в о з в р а т а уп р а в л е н и я

в п р о г р а м м у 1): а — п е р е д а ч а у п р а в л е н и я

с в о зв р а т о м ;

б — п е р е д а ч а у п р а в л е н и я и з п р о гр а м м ы 2

в п р о гр а м м у

3 б е з в о зв р а т а

внутри этого модуля.

Может быть также,

что передачи

между

этими программами

осуществляются

динамически

с помощью

соответствующих макрокоманд. Если

при

передаче

управления

без возврата вызывающая программа

(в примере программа 2)

больше не нужна, память, занимаемая

этой программой,

может

считаться свободной.

 

 

 

 

 

При передаче управления с возвратом в простой структуре необходимо выполнить следующие действия:

а) выделить область сохранения, адрес которой занести в ре­ гистр 13 (для всех передач управления из одной и той же про­ граммы может быть использована одна область сохранения);

б) адрес точки входа, по которому производится передача уп­ равления, занести в регистр 15;

в) построить список параметров, адрес которого занести в регистр 1;

г) обеспечить, чтобы в регистре 14 был адрес возврата (адрес возврата может указывать адрес команды, следующей за коман­ дой передачи управления, а также адрес любой другой команды внутри рассматриваемой программной секции);

д) передать управление по адресу, содержащемуся в регист­ ре 15.

Перечисленные выше действия программист может выполнить, предусмотрев соответствующие команды в своей программе. Для

103

упрощения программирования можно воспользоваться макро­ командой CALL, которая имеет следующий формат;

[и м я ] C A L L { имя

точки

в х о д а 1 [, (п а р а м е т р ы ) [ , V L ] ] [, Ш = » ч и с л о ]

I

(15)

/

Имя точки входа можно указать в макрокоманде либо предва­

рительно заслать ее адрес в регистр 15.

В последнем

случае вме­

сто имени точки входа необходимо записать (15).

параметров

В качестве второго операнда указываются имена

(но не сами параметры), передаваемых

вызываемой

программе.

Если адрес некоторого параметра находится в регистре, то можно вместо имени параметра указать этот регистр, заключив его в круглые скобки, например (10). Параметры отделяются друг от друга запятой. В макрорасширении строится список параметров, адрес которого засылается в регистр 1.

Если указан операнд VL, адрес последнего параметра в списке отмечается единицей в старшем бите. Последний операнд форми­ рует пустую команду, не выполняющую никаких действий (NOP), с кодом 4700 в двух старших байтах. В двух младших байтах ко­ дируется число, указанное в операнде, которое не должно превы­ шать значение 216—1. При этом в регистр 14 в качестве адреса возврата засылается адрес этой команды. Благодаря этому прие­ му в вызываемой программе можно проверить указанное число,

обратившись по адресу в регистре 14.

Это

можно

использовать,

например, для

определения, какая по счету

макрокоманда CALL

в вызывающей

программе осуществила

передачу

управления в

вызываемую программу. Если данный операнд не кодируется, то возврат управления производится к команде, следующей за мак­ рокомандой.

Перед употреблением макрокоманды CALL необходимо обес­ печить область сохранения и заслать ее адрес в регистр 13.

В случае передачи управления без возврата в простой струк­ туре необходимо выполнить следующие действия:

а) обеспечить, чтобы регистр 14 содержал адрес возврата в вызывающую программу более старшего уровня (т. е. в вызываю­ щую программу по отношению к рассматриваемой программе);

б) восстановить содержимое регистров 2—12; в) восстановить в регистре 13 адрес области сохранения, ис­

пользованной в текущей программе; она же будет использоваться в вызываемой программе;

г)

занести в регистр 15 адрес точки входа, по которому произ­

водится передача

управления;

занести в

д)

построить

список параметров, адрес которого

регистр 1;

 

 

е)

передать управление по адресу, содержащемуся

в реги­

стре

15.

 

 

При возврате управления в вызывающую программу, незави­ симо от типа передачи управления, необходимо выполнить сле­ дующие действия:

Ш

а)

обеспечить, чтобы в

регистре 13 содержался

адрес теку­

щей области сохранения;

 

 

б)

восстановить содержимое регистров 2—12 и 14;

в)

заслать код возврата,

кратный 4, в регистр 15,

либо восста­

новить его содержимое из области сохранения, либо не предприни­

мать ничего в отношении регистра 15;

г)

передать управление по адресу, содержащемуся в реги­

стре

14.

Перечисленные действия программист может выполнить, пре­ дусмотрев соответствующие команды в своей программе или ис­ пользовав макрокоманду RETURN, рассмотренную ранее.

Передача управления в динамической структуре обычно связа­ на с поиском программы в библиотеке и загрузкой.ее в оператив­ ную память. Прежде чем обратиться к библиотеке, производят поиск требуемой программы в оперативной памяти. Если обнару­ жена копия требуемой программы в оперативной памяти и уста­ новлено, что она пригодна для использования, то обращение к биб­ лиотеке не производится, что сокращает потери времени.

Библиотека (или библиотечный набор данных) состоит из оглавления библиотеки и совокупности разделов, представляющих собой последовательно организованные наборы данных. Каждый раздел имеет одно основное имя. Кроме основного имени он может иметь ряд дополнительных имен, или псевдонимов. Оглавление библиотеки представляет собой список всех имен всех разделов, где для каждого имени указываются начальный адрес разделов в библиотеке, объем раздела, а также некоторая дополнительная информация. Библиотека может хранить любые данные, в том числе и программы в загрузочном виде. В последнем случае каждая программа библиотеки занимает один раздел. Программы могут иметь имена, хранящиеся в оглавлении. Имя программы может совпадать с именем точки входа. Если программа имеет несколько точек входа, то их имена .могут быть указаны как псевдонимы программы, которые также хранятся в оглавлении. В связи с этим создается возможность осуществлять поиск программы по ее имени или по имени точки входа.

Поиск программы в библиотеке по имени осуществляется в два приема:

а) поиск элемента оглавления библиотеки по заданному имени

и загрузка его в оперативную память;

информации

эле-

б) поиск раздела библиотеки на основании

мента оглавления и загрузка его в оперативную

память,

j

вы­

Первое действие (поиск и загрузка элемента

оглавления)

полняет макрокоманда BLDL. Макрокоманды LINK,

XCTL,

LOAD и ATTACH в зависимости от операндов

могут выполнять

либо только второе действие (в этом случае программист должен предварительно использовать макрокоманду BLDL), либо оба перечисленные действия (программист не должен использовать макрокоманду BLDL: она неявно выдается программой суперви­ зора, осуществляющей поиск).

105

В любом случае, прежде чем начать поиск в библиотеке, необ­ ходимо осуществить ее логическую связь с программой, преду­ смотрев для нее, как для любого набора данных, блок управления данными DCB и макрокоманду OPEN. Для некоторых библиотек это делает операционная система, для других библиотек эти дей­ ствия должен предусмотреть программист.

Любой загрузочный модуль, который может быть запрошен динамически, должен находиться в одной из следующих библиотек (библиотечных наборов данных): общей библиотеке, библиотеке задания, библиотеке пункта задания и личной библиотеке, не яв­ ляющейся библиотекой задания или пункта задания. В качестве библиотеки задания или пункта задания обычно используются личные библиотеки. Однако личная библиотека может не быть библиотекой задания или пункта задания.

Общая библиотека, имеющая имя SYS1.LINKLIB, всегда до­ ступна для всех пунктов всех заданий. Управляющая программа обеспечивает необходимый блок управления данными для этой библиотеки и выдает макрокоманду OPEN, логически связывая эту библиотеку с программой, так что разделы библиотеки стано­ вятся доступными.

Библиотекой задания может стать любая библиотека, если во входном потоке за оператором JOB непосредственно следует опе­ ратор //JOBLIB DD, описывающий одну или несколько библиотек. Эта библиотека доступна для любого пункта в задании. Управ­ ляющая программа обеспечивает необходимый блок управления данными для библиотеки и выдает макрокоманду OPEN, чтобы логически связать ее с программой.

Библиотекой пункта задания может стать любая библиотека, если оператор //STEPLIB DD, описывающий одну или несколько библиотек, находится среди операторов DD некоторого пункта за­ дания. Эта библиотека доступна только для данного пункта. Она заменяет библиотеку задания, если такая имеется, делая ее недо­ ступной в данном пункте задания. Логическая связь библиотеки с программой также выполняется ‘управляющей программой.

Личная библиотека, не являющаяся библиотекой задания или пункта задания, становится доступной в пункте задания путем включения в пункт задания оператора DD, определяющего биб­ лиотеку. Этот оператор может иметь произвольное имя, отличное от JOBLIB, STEPLIB и других специальных имен. Для указанной библиотеки программист должен обеспечить необходимый блок управления данными и выдать макрокоманду OPEN. Блок управ­ ления данными должен содержать имя оператора DD, определяю­ щего библиотеку. Можно использовать несколько личных библио­ тек таким образом: написав для каждой оператор DD и определив соответствующие блоки управления данными.

Следовательно, только в последнем случае программист обес­ печивает логическую связь с программой. Во всех других случаях это делает система. ^

106

Передача управления с возвратом в динамической структуре осуществляется макрокомандой LINK. Допускается также приме­ нение макрокоманды CALL в сочетании с макрокомандами LOAD и DELETE. Макрокоманда CALL осуществляет передачу управле­ ния по заданному адресу или имени без поиска модуля в библио­ теке. В этом случае поиск и загрузка происходят под действием макрокоманды LOAD. В однопрограммном режиме и в режиме мультипрограммирования с фиксированным числом задач без подзадач макрокоманда ATTACH выполняется как макрокоманда LINK, осуществляя передачу управления с возвратом.

Макрокоманда LINK имеет следующий формат:

[ и м я ] L I N K [

Е Р = и м я

точки

в х о д а

 

I

[ , О С В = а д р е с ]

<

E P L O C =

а д р е с

и м ен и

точки

в х о д а )

 

I

D E = а д р е с эл е м е н т а сп иска

j

 

[ , P A R A M = ( п а р а м е т р ы )]

[ , V L = 1 ] [ , Ш

= число]

С помощью операнда ЕР

можно

указать

имя точки входа

непосредственно в макрокоманде, сформировать имя точки входа в некоторой области памяти из 8 байтов. При необходимости имя дополняется пробелами справа до 8 байтов. В этом случае адрес поля с именем точки входа указывается в операнде EPLOC. Если указывается один из отмеченных операндов, поиск в библиотеке состоит из поиска элемента оглавления и поиска самой програм­ мы в библиотеке. Операнд DE используется в сочетании с макро­ командой BLDL.

Когда макрокоманда LINK вызывает модуль из общей библио­ теки или из библиотек задания или пункта задания, то операнд DCB опускается. Если вызывается модуль из личной библиотеки, программист должен построить блок управления данными с по­ мощью макрокоманды DCB, выдать макрокоманду OPEN и ука­ зать адрес блока управления данными в операнде DCB макро­ команды LINK-

С помощью операндов PARAM и VL формируется список пара­ метров для вызываемой программы. Значения указанных операн­ дов задаются аналогично соответствующим операндам макро­ команды CALL, хотя и имеются отличия в форме записи этих операндов.

Операнд ID полностью аналогичен соответствующему операн­ ду макрокоманды CALL.

Перед использованием макрокоманды LINK необходимо обес­ печить область сохранения для вызываемого модуля и ее адрес поместить в регистр 13. Регистры 2—12 не изменяются макро­ командой LINK. Регистр 0 может изменить свое содержимое при передаче управления. В регистр 1 макрорасширение засылает ад­ рес списка параметров, которые указаны в макрокоманде. Регистр

15 содержит адрес точки входа, а регистр

14 — адрес точки воз­

врата. Передача управления с помощью макрокоманды LINK осу­

ществляется посредством операционной

системы. Содержимое

регистров 15 и 14 устанавливается управляющей программой. Воз-

107

врат управления происходит также посредством операционной системы. При выполнении вызываемой программы регистр 14 со­ держит адрес возврата в управляющую программу, которая пе­ редает управление команде, следующей за LINK в вызывающей программе.

Пусть в некоторой программе производится динамическая передача управления программам А и В, находящимся в общей библиотеке. Для общей библиотеки не надо строить блок управле­ ния данными и предусматривать макрокоманду OPEN в програм­ ме. В операторах языка управления заданиями не надо преду­ сматривать оператор DD. Все необходимые действия для связи этой библиотеки с программой делает управляющая программа.

M l

L I N K

E P « = A , P A R A M = (X , Y, Z ) , V L = I

*• •

м 2'

L I N K

 

E P L O C = A D D R S ; P A R A M = ( X ) , V L = 1

М3

L I N K E P = A , P A R A M = ( W , Y , Z ) , V L = 1

w '

D C .

 

 

X

D C .

«

*

Y

D C ,

e

t

Z

D C .

t

A D D R S

D C

 

C L 8 ’B ’

В приведенном примере управление дважды передается про­ грамме А с разными значениями первого параметра. Передача управления программе В производится с использованием операн­ да EPLOC. Имя модуля формируется с помощью 8-байтовой сим­ вольной константы, помеченной меткой ADDRS. Заданное значе­ ние константы приведет к тому, что в первом байте будет записан код будвы В, а в остальных семи байтах — коды пробела.

Если необходимо, чтобы поиск программ производился в биб­ лиотеках задания или пункта задания, то вызывающая программа не меняется, а к операторам языка управления заданиями добав­

ляются операторы DD с меткой // JOBLIB для

библиотеки зада­

ния или с меткой //STERLIB для библиотеки

пункта задания,

как было указано выше. Когда в некотором пункте задания до­ ступны все три библиотеки (пункта, задания и общая), поиск программ производится сначала в библиотеке пункта задания. Предположим, что требуемой программы там не оказалось. Тогда производится поиск в общей библиотеке. Если программы не ока­ залось и там, то пункт задания завершается аварийно. Таким образом, если поиск программ А и В должен осуществляться в библиотеках задания или пункта задания, это не отразится на программе в приведенном выше примере.

Теперь предположим, что программа В находится в личной библиотеке с именем DATA, которая не является ни библиотекой задания, ни библиотекой пункта задания. В. этом случае выше­ приведенная программа будет выглядеть следующим образом:

108

• • *

O P E N

M l

L I N K

* * ш

L I N K

М 3

L I N K

 

М 4

D C B

 

 

W

D C

.

,

X

D C

, .

Y

D C

.

,

Z

D C

.

,

*

(M 4 )

E P = A, P A R A M = (X , Y, Z ) , V L - 1

Е Р = B , D C B = M 4 , P A R A M = ( X ) , V L « 1

E P = A, P A R A M = (W , Y, Z ) , V L = 1

D D N A M E = L I B R , D S O R G = P O , M A C R F = ( R ) ;

Таким образом, для личной библиотеки предусмотрены макро­ команды DCB и OPEN. Строится блок управления данными с мет­ кой М4. В самой программе нигде не указано имя библиотеки. Поэтому программа может работать с любой личной библиотекой, в том числе с библиотекой DATA. Связь программы с личной библиотекой осуществляется при помощи указания в макрокоман­ де DCB имени LIBR оператора DD, который должен содержать описание личной библиотеки. Следовательно, имя оператора DD фиксируется в программе. Имя конкретной библиотеки и ее харак­ теристики должны быть указаны в операторе DD с именем LIBR:

/ / L I B R D D D S N A M Ё = D А Т А , , , .

Если необходимо заменить библиотеку DATA на библиотеку DTI273, то достаточно заменить оператор DD:

 

/ / L I B R D D D S N A M E = D T 1273,

. ,

,

 

Программа

при этом

не меняется. Так

используется

принцип

независимости

программ

от обрабатываемых

наборов

данных,

реализованный в операционной системе ОС ЕС.

В приведенной программе поиск В будет производиться в лич­ ной библиотеке, а поиск программы А — в библиотеках пункта задания, задания или общей библиотеке. Если программа В не будет найдена в личной библиотеке, то пункт задания будет завершен аварийно. Исключение составляет режим мультипрограммирова­ ния с переменным числом задач, в котором после личной библио­ теки осуществляется также поиск и в общей библиотеке.

При многократном вызове одной и той же программы по мак­ рокоманде LINK могут иметь место большие потери времени за счет того, что каждый вызов требует двух обращений к устрой­ ству на каждую библиотеку. Чтобы сэкономить время, можно вос­ пользоваться макрокомандой LOAD, которая осуществляет за­ грузку программы в оперативную память без передачи управле­ ния. В макрокоманде LOAD допускается употребление операндов ЕР, EPLOC, DE и DCB. Их структура и назначение аналогичны операндам макрокоманды LINK. Макрокоманда LOAD помещает адрес точки входа в регистр 0.

Макрокоманда LOAD используется для того, чтобы копия соответствующего загрузочного модуля находилась в основной

109

памяти в области задания, если она ранее не была загружена в общую область. Когда выдается макрокоманда LOAD, управляю­ щая программа ищет загрузочный модуль, как было описано вы­ ше. При возврате управления управляющей программой регистр О содержит адрес точки входа соответствующего загрузочного мо­ дуля. Макрокоманда LOAD применяется только для реентера­ бельных или последовательно используемых модулей. Это связано с тем, что модуль, помещенный в основную память по макрокоман­ де LOAD, остается в ней, даже если он не используется.

Управляющая программа устанавливает

счетчик

обращений

для копии и прибавляет к счетчику единицу

каждый

раз,

когда

запрос макрокоманды LOAD удовлетворяется

этой копией.

Если

счетчик обращения не равен нулю, то копия сохраняется в основ­ ной памяти. Счетчик обращений для копии уменьшается на еди­ ницу, если задача, выдавшая макрокоманду LOAD, выдает мак­ рокоманду DELETE. Когда задача заканчивается, счетчик умень­ шается на число макрокоманд LOAD, выданных для копии при выполнении задачи, минус число выданных макрокоманд DELETE. Когда счетчик обращений для копии в области задания станет равен нулю, область основной памяти, содержащая копию, счи­ тается свободной, а копия — недоступной для использования.

Формат макрокоманды DELETE аналогичен формату макро­ команды LOAD, за исключением того, что не требуется употреб­ лять операнд DCB.

Рассмотрим пример:

МО

Ш

М2

М4

W *

X

Y

Z

L O A D

L I N K

L I N K

D E L E T E

D C , , .

D C . . .

D C . . .

D C , . .

E P = A

E P = A , P A R A M = (X , Y, Z ) , V L = 1

E P = A, P A R A M = ( W , Y , Z ) , V L = l

E P = A

Макрокоманда МО загружает программу А в оперативную па­ мять в раздел пункта задания. Копия этой программы остается в памяти и доступна для использования до тех пор, пока макро­ команда М4 не удалит ее из памяти. При выполнении макро­ команд Ml и М2 обращение к библиотеке не происходит, так как копия программы находится в памяти, а производится передача управления. В результате макрокоманды LINK выполняются очень быстро. После макрокоманды М4 память, занятая программой А, считается свободной. Если в этом месте произойдет передача управления программе А, то потребуется повторная загрузка ее в память.

па

Соседние файлы в папке книги из ГПНТБ