Подобные ошибки переполнения могут легко отслеживаться аппаратно, для чего используется механизм прерываний[ 66 ]
. Прерывания будут рассмотрены в главе 9, но одно из них мы обсудим прямо сейчас: переполнение эффективного адреса (ЕАО).Разберем ситуацию, возникавшую в System/38 при переполнении 16-разрядного смещения. В этом случае аппаратура не увеличивала 32-разрядную сегментную часть адреса. Вместо этого об исключительной ситуации сообщалось VMC, который в каждом конкретном случае заново оценивал ситуацию. VMC рассматривал сегменты, как имеющие длину 16 МБ и состоящие из 256 аппаратных сегментов меньшего размера, и поэтому переполнение 64-килобайтного сегмента в середине 16-мегабайтного сегмента переполнением не считал. С его точки зрения — представления адреса 24/ 24 — переполнением считался только перенос из младших 24 разрядов в старшие 24.
При каждом прерывании по ЕАО VMC увеличивал 32-разрядный аппаратный идентификатор сегмента, проверял, нет ли переноса в старшие 24 разряда, и если обнаруживал, что все в порядке, управление возвращалось аппаратуре. Таким образом, мы постоянно сталкивались с несовпадением схем 32/16 и 24/24.
Когда с течением времени ширина тракта данных процессора выросла с первоначальных 16 до 32, а затем до 48 разрядов, разделение регистров сегмента и смещения в аппаратуре стали менее важны. В IMPI-моделях AS/400 были добавлены команды для поддержки адреса 24/24, что исключило необходимость программной обработки переполнений. Однако в целях совместимости с оригинальным VMC, представление 32/ 16 было в IMPI сохранено.
Эта проблема с адресами была не единственной в оригинальном VMC. Он должен был поддерживать 64-разрядный адрес в указателе MI на аппаратуре с 48-разрядным адресом. Можно было бы попытаться рассматривать 64-разрядные адреса как виртуальные адреса большего размера, которые каким-то образом отображаются в меньшие 48-разрядные виртуальные адреса, но такое решение было отвергнуто. Вместо этого, старшие 16 разрядов 64-разрядного адреса стали рассматриваться как отдельное значение. Мы назвали это 16-разрядное поле расширением идентификатора сегмента, обозначив его номером IPL. При всякой перезагрузке системы номер IPL увеличивался на единицу, что каждый раз давало новое 48-разрядное адресное пространство. На рисунке 8.2 показаны поля, составляющие 64-разрядный адрес в указателе MI.
Первоначально заголовок сегмента, описанный в главе 5, содержал поле с 16-разрядным расширением идентификатора этого сегмента. Когда программа MI пыталась использовать указатель на System/38 и на ранних моделях AS/400, для проверки битов тега и загрузки 48-разрядного адреса в процессорный регистр, использовалась специальная команда IMPI под названием «Загрузить и проверить теги» («lvt»). Команда «lvt» аналогична «lq» на RISC-процессорах, но у первой была дополнительная задача. Она должна была сравнить старшие 16 разрядов адреса в указателе с полем расширения идентификатора в заголовке сегмента и гарантировать их совпадение с адресом сегмента. После первого обращения для доступа к сегменту использовался только 48-разрядный адрес.
Как уже говорилось, всякий раз при увеличении номера IPL мы получали новое адресное пространство для временных объектов. Временные объекты разрушаются при выполнении IPL, в отличие от постоянных, продолжающих существовать и после перезагрузки. Так как аппаратура использовала только 48 разрядов, один и тот же 48-разрядный адрес не мог быть задействован для постоянных объектов повторно, за исключением случая, когда постоянный объект по этому адресу был явно удален во время предыдущего сеанса работы ОС. Тогда от него оставались только заголовки, что обнаруживалось при первом использовании полного 64-разрядного адреса, начальные 16 разрядов которого содержат номер IPL. Так как номера IPL различались, то при повторном использовании 48-разрядного адреса конфликтов не возникало. Еще раз подчеркну, что заголовки сохраняются только при разрушении постоянных объектов — при разрушении временного объекта не остается ничего.
Так как мы решили не использовать на System/38 48-разрядный адрес повторно до следующей перезагрузки, встал вопрос о том, что однажды все доступные адреса могут быть исчерпаны. В поисках ответа на него, мы провели некоторые интересные подсчеты. В соответствии с их результатами, если выполнять одну IPL в день 365 дней в году, то повторное использование номера IPL потребуется через 180 лет. Итак, опасности, что расширения идентификаторов сегментов будут повторяться, не существовало. Зная проектируемую производительность будущих процессоров, мы могли вычислить максимальное число 64-килобайтных сегментов, которое будет сгенерировано в интервале между ежедневными IPL. Эти расчеты также показали, что проблемы нет. И все же прогноз оказался неверным — некоторые большие AS/400 стали выходить за границы адресов[ 67 ]
.