Вторая часть разрешенного указателя содержит 64-разрядный адрес. Так было всегда, и многие годы это вызывало путаницу: каков все же размер виртуального адреса System/38 и AS/400, 48- или 64-разрядный? С появлением новых RISC-моделей AS/400 путаница прекратилась: теперь адрес 64-разрядный. А в System/38 и ранних моделях AS/400 он был и таким, и таким. В MI адрес всегда был 64-разрядным, а аппаратура работала с 48-разрядным адресом. Как они уживались вместе — тема следующего раздела.
Появление новых RISC-моделей с полностью 64-разрядными аппаратными адресами устранило большинство проблем, связанных со смешением 64- и 48-разрядной адресации в предыдущих моделях. Чтобы понять, почему 64-разрядный аппаратный адрес так важен, рассмотрим первоначальную 48-разрядную реализацию.
48-разрядный адрес появился в результате компромисса. Проектировщики ОС System/38 планировали адрес размером в 64 бита. После того, как размер указателя был определен в 16 байтов, для 64-разрядного адреса появилось достаточно места. Проблемы возникли на аппаратном уровне. Чем больше разрядов в адресе, тем больше размер регистров процессора. Больший размер регистров требовал большего числа цепей и повышал стоимость аппаратных средств.
Техническим менеджером System/38 был Рей Клотц, не видевший надобности в таком большом адресе. Его многократно пытались уговорить, но Рей так и не поддался на уверения, что 64-разрядного адреса хватит навечно. В середине 70-х годов подразделение IBM по мэйнфреймам собиралось объявить о новом большом адресе для System/370, получившем название расширенной адресации (XA). С применением ХА адрес System/370 должен был вырасти с 24 до 31 разряда. Рей обвинял нас в желании непременно превзойти System/370 и утешал тем, что 32 разряда все равно больше чем 31. «Вы побьете их и одним разрядом, а больше и не надо», — как бы говорил он. Мы, в свою очередь, утверждали, что 32-разрядный адрес не будет работать с одноуровневой памятью System/38, и что нужны 64 разряда. Когда стало очевидным, что спор зашел в тупик, мы поступили так, как будто торговались о цене подержанной машины: поделили пополам разницу между 32 и 64. Таким образом, получился 48-разрядный адрес.
Для поддержки сегментированной памяти 48-разрядный адрес разделяется надвое. Старшие разряды задают сегмент, а младшие, называемые смещением — байт внутри сегмента. Мы решили использовать для задания сегмента старшие 32 разряда, а для смещения — младшие 16, назвав все это адресом 32/16. 16 разрядов смещения означали размер сегмента в 64 КБ (216 = 64 КБ).
Оригинальная аппаратура процессора System/38 имела 16-разрядный тракт данных и 16-разрядный сумматор для вычислений. Смысл использования адреса форматом 32/16 был в том, чтобы смещение адреса не выходило за размер тракта данных, так как очень часто обновлялось. Мы решили обрабатывать 32-разрядный идентификатор сегмента не в тракте данных процессора, а вне его, в отдельном наборе сегментных регистров. К этим сегментным регистрам был возможен доступ со стороны процессора, но они не могли обновляться «на месте».
Программисты, отвечавшие за ПО ОС ниже MI (первоначально VMC) не были согласны с такой адресацией (32/16), так как считали, что размер сегмента в 64 КБ слишком мал. Первоначально они предполагали создать сегментные группы, каждая из которых содержала бы один или несколько таких 64-килобайтных сегментов, но, в конце концов, решили, что сегментная группа всегда должна состоять из 256 сегментов. При выделении нового сегмента как части вновь создаваемого объекта его размер всегда будет равен 16 МБ (256 Г 64 КБ = 16 МБ). С этого момента мы говорили о 64-килобайтных и 16-мегабайтных сегментах, впрочем, называя иногда вторые сегментной группой. Этот разнобой в терминологии продолжался до появления процессоров PowerPC и SLIC. Если Вы возьмете в руки калькулятор или таблицу степеней двойки, то поймете, почему программисты VMC, имевшие дело с 16-мегабайтными сегментами, рассматривали 48-разрядный адрес как имеющий 24-разрядный идентификатор сегмента и 24-разрядное смещение (ведь 224 = 16 МБ).
Представление адреса 24/24, использовавшееся VMC, не совпадало с представлением 32/16, использовавшимся аппаратурой. Возник вопрос: каким способом обрабатывать переполненное поле смещения адреса? Рассматривая объекты, мы говорили, что они состоят из одного или нескольких несмежных сегментов, и что ни один сегмент не может содержать части более чем одного объекта. Очевидно, что смещение адреса за границу сегмента в следующий сегмент нежелательно, так как последний может относиться к другому объекту. Следовательно, такое смещение, например, адреса в пространственном указателе за пределы ассоциированного пространства объекта, надо предотвратить. Определяется такое переполнение адреса следующим способом: после каждого увеличения адреса проверяется, не было ли переноса из разрядов смещения в разряды идентификатора сегмента. Такой перенос и означает попытку обратиться к следующему сегменту.