Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Лекция 16. Система прерываний




16.1. Назначение и распределение прерываний

В процессе работы ЭВМ очень часто возникает необходимость временно остановить выполнение основной программы для отработки некоторых специальных инструкций (нажатие клавиши, ход системных часов, готовность внешних устройств передать или принять данные и т.д.). С этой целью в CPU встроена эффективная система прерываний. Каждому прерыванию поставлен в соответствие номер (тип) 0..255. Прерывания с меньшим номером имеют более высокий приоритет.

Прерывания могут быть внешними (аппаратными), внутренними и командными. Запрос на прерывание вынуждает CPU после выполнения 1-2 текущих команд перейти к выполнению программы прерывания. Для этого в стеке запоминается адрес возврата на основную программу CS:IP и регистр флагов F (автоматически), а также содержимое регистров, которые потребуются для выполнения программы прерывания (программным путем). После выполнения прерывания восстанавливается состояние регистров CPU и продолжается выполнение основной программы.

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

Командные прерывания, определяемые пользователем, осуществляются по двухбайтовым командам INT n (кроме специальной однобайтовой команды INT0, по которой вырабатывается прерывание по переполнению, если установлен флаг OF=1). Программное прерывание во многом аналогично выполнению подпрограммы.

16.2. Аппаратные прерывания

Аппаратные прерывания обеспечивают реакцию процессора на события, происходящие асинхронно по отношению к исполняемому программному коду. По возникновении такого события адаптер (контроллер) устройства формирует запрос прерывания, который поступает на вход контроллера прерываний. Контроллер прерываний формирует общий запрос прерывания для процессора, а когда процессор подтверждает получение этого запроса, контроллер сообщает процессору вектор прерывания, по которому выбирается программная процедура обработки прерываний. Процедура должна выполнить действия по обслуживанию данного устройства, включая сброс его запроса, и отправить команду завершения в контроллер прерываний, что дает возможность отреагировать на следующие события. Логика работы системы прерываний и программная модель контроллера прерываний, совместимого с микросхемой i8259A, являются важной частью стандартизации архитектуры PC-совместимых компьютеров.

16.2.1. Немаскируемые прерывания

Немаскируемые прерывания (Non-Maskable Interrupt, NMI) в PC используются для сигнализации о фатальных аппаратных ошибках. На немаскируемое прерывание процессор реагирует всегда (если завершено обслуживание предыдущего немаскируемого прерывания); этому прерыванию соответствует фиксированный вектор 2. Сигнал на линию NMI (вход процессора) приходит от схем контроля памяти (четности или ЕСС), от линий контроля шины ISA (IOСНК) и шины PCI (SERR#).

Источниками прерывания SMI являются схемы чипсета, участвующие в управлении энергопотреблением, а также контроллер USB при эмуляции традиционных клавиатуры и мыши. Это прерывание имеет наивысший приоритет и обслуживается несколько иначе, чем «классические» прерывания. Здесь процессор не выполняет вызов процедуры, описанной в таблице прерываний, а переходит в режим SMM. После обработки возможен рестарт (повторное исполнение) инструкции останова (HALT) и инструкций ввода-вывода. Возможность рестарта инструкции ввода-вывода используют, например, когда прикладная программа (или системный драйвер) пытается обратиться операцией ввода-вывода к периферийному устройству, находящемуся в «спящем» режиме. Обработчик SMI «будит» устройство, после чего операция ввода-вывода рестартует и прикладное ПО (или драйвер) «не замечает», что устройство пребывало в спячке. Таким образом, управление потреблением может быть организовано на уровне BIOS способом, совершенно прозрачным для программного обеспечения (в том числе и ОС).

16.2.2. Маскируемые прерывания

Маскируемые прерывания используются для сигнализации о событиях в устройствах. Реакция процессора на маскируемые прерывания может быть задержана сбросом его внутреннего флага IF (инструкция CLI запрещает прерывания, STI – разрешает). По возникновении события, требующего реакции, адаптер (контроллер) устройства формирует запрос прерывания, который поступает на вход контроллера прерываний. Задача контроллера прерываний – довести до процессора запрос прерывания и сообщить вектор, по которому выбирается программная процедура обработки прерываний. В IBM PC-совместимых компьютерах применяется два основных типа контроллеров прерываний:

· Периферийный контроллер прерываний (Peripheral Interrupt Controller, PIC) программно совместим с традиционным контроллером 8259А, использовавшимся еще в первых моделях IBM PC. Со времен IBM PC/AT применяется связка из пары каскадно соединенных контроллеров PIC, позволяющая обслуживать до 15 линий запросов прерываний.

· Усовершенствованный периферийный контроллер прерываний (Advanced Peripheral Interrupt Controller, APIC) введен в компьютеры для поддержки мультипроцессорных систем на базе процессоров 4-5-го поколений (486 и Pentium) и используется поныне для более поздних моделей процессоров. Помимо поддержки мультипроцессорных конфигураций, современный контроллер APIC позволяет увеличивать число доступных линий прерываний и обрабатывать запросы прерываний от устройств PCI, посылаемые через механизм сообщений (MSI). Компьютер, оснащенный контроллером APIC, обязательно имеет возможность функционировать и в режиме, совместимом со стандартной связкой пары PIC. Этот режим включается по аппаратному сбросу (и включению питания), что позволяет использовать старые ОС и приложения MS-DOS, «не знающие» APIC и мультипроцессирования.

Традиционная схема формирования запросов прерываний с использованием пары контроллеров PIC изображена на рис. 16.1. На входы контроллеров прерываний поступают запросы от стандартных устройств (клавиатура, системный таймер, CMOS-таймер, сопроцессор), периферийных контроллеров системной платы и от карт расширения. Традиционно все линии запросов, не занятые перечисленными устройствами, присутствуют на всех слотах шины ISA/EISA. Эти линии обозначаются как IRQx и имеют общепринятое назначение. Часть этих линий отдается в распоряжение шины PCI.

Рис.16.1. Коммутация запросов прерываний

Для запросов прерывания с шины PCI (рис. 16.1) задействуют 4 линии запросов прерывания, которые обозначают как INTR А, В, С, D. Эти линии работают по низкому уровню, что дает возможность их совместного (разделяемого) использования. Линии циклически сдвигаются в слотах и независимо коммутируются на доступные линии IRQx с помощью конфигурационных регистров чипсета.

В табл. 16.1 запросы расположены в порядке убывания приоритета. Номера векторов, соответствующих линиям запросов контроллеров, система приоритетов и некоторые другие параметры задаются программно при инициализации контроллеров PIC или APIC. Эти основные настройки остаются традиционными для совместимости с программным обеспечением, но различаются для ОС реального и защищенного режимов. Так, например, в ОС Windows базовые векторы для ведущего и ведомого контроллеров – 50h и 58h соответственно.

Таблица 16.1

Аппаратные прерывания (в порядке убывания приоритета)

Имя (номер) Вектор (реальный режим) Вектор (ОС Windows) Контроллер /маска Описание
NMI 02h 02h - Контроль канала, четность памяти (в XT – сопроцессор)
IRQ0 08h 50h #1/1h Таймер (канал 0 8253/8254)
IRQ1 09h 51h #1/2h Клавиатура
IRQ2 0Ah 52h #1/4h XT – резерв, AT – недоступно (под-ключается каскад IRQ8-IRQ15)
-- -- -- -- --
-- -- -- -- --
IRQ6 0Eh 55h #1/40h FDC – контроллер НГМД
IRQ7 0Fh 56h #1/80h LPT1 – принтер

Запросы прерываний 0, 1, 8 и 13 на шины расширения не выводятся

Каждому устройству, для поддержки работы которого требуются прерывания, должен быть назначен свой номер прерывания. В процессе назначения прерываний может участвовать система РпР для шин ISA и PCI: для распределения линий запросов между шинами служат специальные параметры CMOS Setup. Современные ОС имеют возможность изменить назначение запросов относительно распределения, сделанного через CMOS Setup.

16.3. Традиционный контроллер прерываний – PIC

Контроллер прерываний (PIC) 8259А является периферийным устройством, которое связано с процессором через ту или иную шину расширения ввода-вывода. По этой шине процессор может обращаться к регистрам контроллера, программируя его режимы и управляя им, а также получать от контроллера 8-битный вектор прерывания, для чего в интерфейсе системной шины процессора и шины расширения имеется специальная команда подтверждения прерывания (INTA). Контроллер 8259А имеет 8 входов запросов от источников и один выход общего запроса. Каждому из входов соответствует свой вектор; программированием регистров контроллера задается номер вектора для входа 0, остальным входам соответствуют последующие номера векторов. Каждый вход может быть программно замаскирован – тогда он не вызывает сигнал общего запроса.

Контроллер занимает два адреса в пространстве ввода-вывода, программное обращение позволяет управлять режимами работы контроллера, а также приоритетами и масками запросов. Кроме того, контроллер позволяет работать в режиме опроса (poll mode), или полинга (polling), обеспечивая идентификацию источника прерывания (с учетом приоритетов) без выработки общего запроса.

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

В любом случае сигнал запроса аппаратного прерывания IRQx должен удерживаться генерирующей его схемой, по крайней мере, до цикла подтверждения прерывания процессором – именно в этот момент PIC определяет самый приоритетный незамаскированный запрос и по нему формирует вектор. Если к этому моменту запрос окажется снятым, источник прерывания корректно идентифицирован не будет, и контроллер сообщит ложный вектор прерывания (spurious interrupt), соответствующий его входу с максимальным номером (IRQ7 для первого контроллера и IRQ15 для второго). Обычно периферийные устройства строят так, что сигнал запроса сбрасывается при обращении программы обслуживания прерывания к соответствующим регистрам адаптера, так что ложных прерываний возникать не должно.

Один контроллер PIC 8259А позволяет обслуживать 8 запросов прерываний; в PC/AT применяется каскадное соединение двух контроллеров, один из которых является ведущим, другой – ведомым. Ведущий контроллер 8259А#1обслуживает запросы 0, 1, 3-7; его выход подключается ко входу запроса прерываний процессора. К его входу 2 подключен ведомый контроллер 8259А#2,который обслуживает запросы 8-15. При этом поддерживается вложенность приоритетов – запросы 8-15 со своим рядом убывающих приоритетов вклиниваются между запросами 1 и 3 ведущего контроллера, приоритеты запросов которого также убывают с ростом номера. В XT каскадирование не применялось, и один контроллер 8259А обслуживал все 8 линий запросов.

В IBM PC/XT/AT используется специальный режим вложенных прерываний с фиксированным приоритетом и автоматическим неспецифическим завершением. После инициализации (процедурой POST и при загрузке ОС) все неиспользуемые входы контроллеров замаскированы (на запросы прерываний не реагируют), а их векторы прерываний указывают на «заглушку» – процедуру с единственной инструкцией IRET. Для подключения обработчика прерывания от устройства первым делом следует загрузить обработчик в память и установить указатель на него в таблице прерываний. Далее следует демаскировать соответствующий ему вход в контроллере прерываний. Если обработчик прерывания удаляется из памяти, предварительно должен быть замаскирован соответствующий ему вход контроллера. Все изменения в таблице прерываний должны выполняться при замаскированных прерываниях, чтобы избежать попытки использования вектора в процессе его модификации (это приведет к «вылету» программы – обращению по некорректному адресу).

В современных системных платах функции контроллеров прерываний возлагаются на чипсет, который может иметь и более гибкие средства управления, чем пара контроллеров 8259А. Процедура инициализации контроллеров может и отличаться от традиционной, но ею занимается тест POST, который «знает» особенности системной платы. Однако в операционном режиме всегда сохраняется программная совместимость с 8259А. При работе с контроллером прерываний от программы требуется лишь управлять маской своего запроса (при инициализации программы нужно обнулить маску требуемого запроса) и корректно завершать обработку прерываний. Каждая процедура обработки аппаратного прерывания должна завершаться командой EOI(End Of Interruption), посылаемой контроллеру:

· для 1-го контроллера – посылка байта 20h по адресу 020h;

· для 2-го контроллера – посылка байта 20h по адресу 0A0h; программный вызов прерывания 0Ah – завершение для ведущего контроллера; для некоторых старых версий BIOS был необходим явный сброс маски запроса в регистре 2-го контроллера.

Некорректно завершенная процедура не позволит повторно использовать данный или другие запросы прерываний.

16.4. Улучшенный контроллер прерываний – APIC

Контроллер APIC в первую очередь предназначен для симметричных мультипроцесорных систем, в которых все процессоры разделяют общие устройства ввода-вывода и общие контроллеры прерываний. Однако APIC используется и в однопроцессорных системных платах. Система с APIC состоит из локальных контроллеров, установленных в процессорах, и контроллеров прерываний от ввода-вывода (одного или нескольких). Все контроллеры APIC соединены между собой локальной шиной, по которой они обмениваются друг с другом сообщениями. Задача каждого локального контроллера (local APIC) – трансляция сообщений, принятых по локальной шине, в сигналы, вызывающие все аппаратные прерывания своего процессора, – маскируемые (INTR), немаскируемые (NMI) и системного управления (SMI). Кроме того, локальные контроллеры APIC позволяют каждому процессору генерировать прерывания для других процессоров. Локальный контроллер имеет внутренний интервальный таймер, позволяющий вырабатывать прерывания через программируемый интервал времени. Контроллер прерываний от ввода-вывода (I/O APIC) преобразует запросы аппаратных прерываний от устройств в сообщения протокола локальной шины APIC. В мультипроцессорном режиме он отвечает за распределение прерываний по процессорам, для чего может потребоваться статическое или динамическое распределение. В случае статического распределения для каждого номера прерывания указывается номер процессора, который его обслуживает. В случае динамического распределения каждое прерывание направляется наименее приоритетному в данный момент процессору. Этот же контроллер отвечает за распространение сигналов о системных событиях (NMI, INIT, SMI) и межпроцессорных прерываний.

Контроллер I/O APIC является частью чипсета системной платы

Для симметричных систем допустимы векторы в диапазоне 10h-FEh. Уровень приоритета прерывания определяется номером его вектора, деленным на 16. Самый приоритетный уровень – нулевой.

Контроллер I/O APICпозволяет вырабатывать значительное число запросов прерываний; каждому запросу соответствует свой элемент в таблице перенаправления, находящейся в APIC. Каждый элемент определяет способ реакции на свой запрос, вектор прерывания и процессор (процессоры) назначения, который должен его обработать. С запросами связаны индивидуальные входы INTINn; определенный уровень или перепад сигнала на этих входах вызывают соответствующие запросы. Чувствительность и вектор (а следовательно, и приоритет) для каждого запроса программируются индивидуально. Более совершенные модели I/O APIC позволяют вызывать прерывание записью номера входа в регистр контроллера, что, например, используется для поддержки прерываний MSI на шине PCI. При этом возможна и экономия сигнальных входов: APIC может иметь входы INTINn не для всех номеров запросов, вырабатываемых записью в этот регистр. Однако число запросов всегда ограничивается размером таблицы перенаправления.

Регистры контроллеров APIC отображаются на пространство памяти. Все локальные контроллеры APIC используют один и тот же диапазон адресов (по умолчанию базовый адрес – FEE0 0000h) – к их регистрам обращаются только программы, исполняемые на их же процессорах, и эти обращения не выводятся на системную шину. Контроллеры I/O APIC доступны всем процессорам, по умолчанию базовый адрес первого I/O APIC – FEC0 0000h, базовые адреса остальных контроллеров (если таковые имеются) назначаются последовательно с шагом l0000h.

Выделение для сообщений APIC отдельной локальной шины позволяет освободить системную шину процессора от трафика, связанного с обслуживанием прерываний (подачи подтверждений прерываний для получения вектора). В современных процессорах используется локальная шина, состоящая из трех сигнальных линий: PICD[1:0] – двунаправленная шина данных и PICCLK – сигнал синхронизации (тактовая частота). Протокол шины обеспечивает распределенный механизм арбитража и надежную доставку сообщений. Сообщения, передаваемые по локальной шине APIC, программно невидимы; реализация и протокол шины могут быть изменены производителями процессоров и чипсетов системных плат, но это не отразится на ПО.

Помимо использования последовательной локальной шины, есть и иной вариант доставки сообщений к локальным контроллерам APIC – в этом варианте происходят обращения к пространству памяти. Для этого локальные контроллеры APIC настраиваются на отслеживание операций записи по определенным адресам. Источник сообщений выполняет операцию записи в пространство памяти, в которой и адрес, и данные несут информацию о событии прерывания. В качестве источника сообщений может выступать расширенный контроллер,называемый I/0(x)APIC.

16.5. Проблема разделяемых прерываний

Линии запросов прерываний в компьютере, насыщенном периферийными устройствами, являются самым дефицитным ресурсом, поэтому приходится использовать эти линии совместно, то есть применять разделяемые прерывания (shared interrupts) между несколькими устройствами. Обработчики прерываний (программы) от разных устройств, имеющих одну линию запроса (и следовательно, общий вектор прерывания), должны быть выстроены в цепочку.

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

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

Для шины PCI с аппаратной точки зрения проблема разделения прерываний решена – здесь активным уровнем запроса является низкий, и контроллер прерываний чувствителен к уровню, а не к перепаду. Для шины ISA с ее запросами прерываний по положительному перепаду разделяемость прерываний невозможна. Исключения составляют системные платы и устройства с поддержкой ISA РпР, которые можно заставить работать и по низкому уровню.

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

В первых версиях (до PCI 2.2 включительно) не было общепринятого способа программной индикации и запрета прерываний. К сожалению, в конфигурационных регистрах не нашлось стандартного места для бита, индицирующего введение запроса прерывания данным устройством, – тогда бы в прерываниях для PCI не было бы проблем с унификацией разделяемых прерываний. В каждом устройстве для работы с прерываниями используются свои специфические биты операционных регистров, относящихся к пространству памяти или ввода-вывода (иногда и к конфигурационному пространству). При этом определить, является ли данное устройство в текущий момент источником прерывания, может только его обработчик прерывания (Interrupt Service Routine, ISR), входящий в драйвер данного устройства. Таким образом, у ОС нет иной возможности диспетчеризации разделяемых прерываний, кроме как выстроить их обработчики в цепочку. За расторопность и корректность ISR отвечает его разработчик. В PCI 2.3 наконец-то появился фиксированный бит (Interrupt Status) в регистре состояния конфигурационного пространства устройства (функции), по которому ОС может определить источник разделяемого прерывания и вызвать только его ISR. Однако упоминание о поддержке PCI 2.3 в описаниях устройств и операционных систем встречается нечасто.

Обработчики прерываний устройств должны вести себя корректно, учитывая возможность попадания в цепочку обработчиков разделяемого прерывания. Встречается типичная ошибка обработчика прерываний: прочтя регистр состояния устройства и не обнаружив признака запроса, драйвер «на всякий случай» выполняет сброс всех источников запроса (а то и сброс всего устройства). Эту ошибку порождает незадачливый разработчик драйвера, не учитывающий возможности разделения прерываний и не доверяющий разработчикам аппаратных средств. Увидев в процессе отладки эту неожиданную ситуацию (прерывание вызвано, а источник не виден), он ее «учитывает» введением «вредного» фрагмента программного кода. Вредность заключается в том, что с момента чтения регистра устройства (не давшего признака запроса) и до выполнения этого ненужного сброса в устройстве может возникнуть запрос прерывания, который будет «вслепую» сброшен и, следовательно, потерян.

Однако и при корректности обработчиков, выстроенных в цепочку, разделяемые прерывания для разнотипных устройств в общем случае работоспособными считать нельзя – возможны потери прерываний от устройств, требующих быстрой реакции. Это может происходить, если обработчик такого устройства окажется в конце цепочки, а предшествующие ему обработчики будут «нерасторопными» (не самым быстрым способом обнаружат, что прерывание – чужое). Поведение системы в такой ситуации может меняться в зависимости от порядка загрузки драйверов. Для нескольких однотипных устройств (например, сетевых адаптеров на однотипных микросхемах контроллеров), пользующихся одним драйвером, механизм разделяемых прерываний работает вполне успешно.

Проявления конфликтов по прерываниям могут быть разнообразными. Сетевая карта не сможет принимать кадры из сети или будет их иногда терять (при этом она может их успешно посылать); у устройств хранения доступ к данным будет поразительно медленным (иногда можно минутами ожидать, например, появления информации о файлах и каталогах) или даже невозможным; звуковые карты будут молчать или «заикаться»; на видеопроигрывателях изображение будет дергаться и т.д. Конфликты могут приводить и к внезапным перезагрузкам компьютера, например, по приходе кадра из сети или сигнала от модема. Спасением от проблем разделяемости может быть перестановка карт PCI в подходящий слот, в котором конфликты не наблюдаются (это не значит, что их нет). Однако попадаются «подарки разработчиков» интегрированных плат, у которых из нескольких слотов PCI неразделяемая линия прерывания есть только у одного (а то и нет вообще). Такие недуги без скальпеля и паяльника, как правило, не лечатся. Более радикальный способ – переход на сигнализацию прерываний через сообщения (MSI).

Контрольные вопросы

1. Возможно ли функционирование ПЭВМ без прерываний?

2. Дайте классификацию типов прерываний.

3. Приведите описание контроллера прерываний PIC.

4. Приведите описание контроллера прерываний APIC.

5. Зачем в программе прерывания в порт 20h заносится число 20h?

 




Поделиться с друзьями:


Дата добавления: 2014-12-07; Просмотров: 1861; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.05 сек.