Э. Таненбаум - Архитектура компьютера (1127755), страница 112
Текст из файла (страница 112)
Различие состоит в том, что, когда управление переходит от А к В, процедура В начинает выполняться с самого начала; а при передаче управления из В обратно в А выполнение процедуры А продолжается не с начала, а с того момента, за которым последовал вызов процедуры В. Если А работает некоторое время, а потом снова вызывает процедуру В, выполнение В снова начинается с самого начала, а не с того места, после которого управление было возвращено процедуре А. Если процедура А вызывает процедуру В много раз, процедура В каждый раз начинается с начала, а процедура А уже никогда больше с начала не начинается. Это различие отражается в способе передачи управления между А и В. Когда процедура А вызывает В, она использует команду вызова процедуры, которая помещает адрес возврата (то есть адрес той команды, которая в программе располагается следом за процедурой) в такое место, откуда его потом легко будет извлечь, например на вершину стека.
Затем она помещает адрес процедуры В в счетчик команд, чтобы завершить вызов. Для выхода из процедуры В используется не команда вызова процедуры, а команда выхода из процедуры, которая просто выталкивает адрес возврата из стека и помещает его в счетчик команд. Однако иногда нужно, чтобы обе процедуры (А и В) вызывали друг друга в качестве процедуры, как показано на рис. 5.27. При возврате из В в А процедура В совершает переход к тому оператору, перед которым последовал вызов процедуры В.
Когда процедура А передает управление процедуре В, она возвращается не к самому началу В (за исключением первого раза), а к тому месту, перед которым произошел предыдущий вызов А. Две процедуры, работающие подобным образом, называются сопрограммами. Сопрограммы обычно используются для параллельной обработки данных на одном процессоре. Каждая сопрограмма работает как бы одновременно с другими сопрограммами, как будто у нее есть собственный процессор.
Такой подход упрощает программирование некоторых приложений. Он также полезен для проверки программного обеспечения, предназначенного для мультипроцессора. Обычные команды СА(.~. и йЕТ0йй для вызова сопрограмм не подхолят, поскольку, хотя адрес перехода берется из стека, как и при возвращении управления, но в отличие от возвращения управления при вызове сопрограммы адрес возврата помещается в определенном месте, чтобы в последующем к нему вернуться.
Было бы неплохо, если бы существовала команда, в которой вместо вершины стека использовался счетчик команд. Эта команда сначала должна выталкивать старый адрес возврата из стека и помещать его во внутренний регистр, затем помещать счетчик команд в стек и, наконец, копировать содержание внутреннего регистра в счетчик команд.
Поскольку одно слово выталкивается из стека, а другое помещается в стек, состояние указателя стека не меняется. Такая команда встречается очень редко, поэтому в большинстве случаев ее приходится моделировать из нескольких команд. Поток управления 451 Процедура А вызывается из основной программы Процедура А возвращает управление основной программе Рис. 6.27.
После завершения сопрограммы выполнение начинается с того места, на котором оно завершилось в прошлый раз, а не с самого начала Перехват исключений Перехват исключений — зто особый тип вызова процедур, который происходит при определенных условиях, обычно очень серьезных, но редко встречающихся. Один из примеров такого условия — переполнение. В большинстве процессоров, если результат выполнения арифметической операции превышает самое большое допустимое число, происходит исключение, которое перехватывается.
Это значит, что поток управления переходит в какую-то фиксированную ячейку памяти, а не продолжается последовательно дальше. В этой фиксированной ячейке находится команда перехода к специальной процедуре (обработчику исключений), которая выполняет какое-либо определенное действие, например печатает сообщение об ошибке. Если результат операции находится в пределах допустимого, исключения не происходит.
Важно то, что исключения могут вызываться программно, а перехватываются они аппаратно или на микропрограммном уровне. Помимо перехвата исключения, есть и другой способ определения факта переполнения. Для этого нужно иметь 1-разрядный регистр, который будет устанавливаться всякий раз, когда происходит переполнение. В этом случае программисту, который хотел бы 452 Глава 5. Уровень архитектуры набора команд проверять результат на переполнение, после каждой арифметической команды пришлось бы включать в программу команду перехода по переполнению, что очень неудобно.
То есть по сравнению с явной программной проверкой перехват исключений экономит время и память. Перехват исключений можно реализовать не только аппаратно, но и с помощью микропрограммы путем той же явной проверки. В этом случае при обнаружении факта переполнения адрес обработчика исключений загружается в счетчик команд. Проверка на уровне микропрограммы требует меньше времени, чем проверка на уровне программы, поскольку может выполняться одновременно с каким-либо другим действием. Кроме того, такая проверка экономит память, поскольку ее можно реализовать только в одном месте, например в основном цикле микропрограммы независимо от того, сколько арифметических команд имеется в основной программе.
К наиболее распространенным условиям, которые могут вызывать исключения, относятся: переполнение и исчезновение значащих разрядов при выполнении операций с плавающей точкой, переполнение при выполнении операций с целыми числами, нарушения защиты, неопределяемый код операции, переполнение стека, запуск несуществующего устройства ввода-вывода, вызов слова с нечетным адресом, деление на О. Прерывания Прерывания — это изменения в потоке управления, вызванные не самой программой, а чем-либо другим. Обычно прерывания связаны с процессом ввода- вывода. Например, программа может дать команду диску начать передачу информации и инициировать прерывание, как только передача данных завершится.
Как и в случае исключений, при прерываниях работа программы останавливается, и управление передается программе обработки прерываний (1пгеггирг Яегу1се Копг1пе, 1ЯК), или обработчику прерываний, который выполняет определенные действия. После завершения этих действий обработчик прерываний передает управление прерванной программе. Она должна заново начать прерванный процесс в том же самом состоянии, в котором находилась в момент прерывания. Это значит, что прежнее состояние всех внутренних регистров (то есть состояние, которое было до прерывания) должно быть восстановлено. Различие между исключениями и прерываниями заключается в том, что исключения синхронны по отношению к программе, а прерывания асинхронны. Если многократно перезапускать программу с одними и теми же входными данными, исключения каждый раз будут происходить в одних и тех же местах программы, а прерывания — нет (в нашем примере с диском прерывание произойдет только тогда, когда диск завершит передачу данных, а не когда этого потребует программа).
Причина воспроизводимости исключений и невоспроизводимости прерываний состоит в том, что первые вызываются программой непосредственно, а вторые — опосредованно. Чтобы понять, как происходят прерывания, рассмотрим обычный пример: компьютеру нужно вывести на терминал строку символов. Программа сначала собирает в буфер все символы, предназначенные для вывода на экран, инициа- Поток управления 453 лизирует глобальную переменную рог, которая должна указывать на начало буфера, и делает вторую глобальную переменную сопит. равной числу символов, выводимых на экран. Затем программа проверяет, готов ли терминал, н, если готов, выводит на экран первый символ (например, используя регистры, показанные на рис.
5.20). Начав процесс ввода-вывода, центральный процессор освобождается и может запустить другую программу или сделать что-либо еще. Через некоторое время символ отображается на экране. После этого может быть инициировано прерывание. Ниже перечислены основные шаги (в упрощенной форме).
Действия аппаратного обеспечения: Е Контроллер устройства нагружает линию прерывания на системной шине. 2. Когда центральный процессор оказывается готовым к обработке прерывания, он выставляет на шине символ подтверждения прерывания. 3. Когда контроллер устройства обнаруживает, что сигнал прерывания подтвержден, он помещает небольшое целое число на информационные линии, чтобы «представиться» (то есть, показать, что за устройство является источником прерывания).