Относительная адресация в обязательном предполагает наличие полного адреса в каком-то регистре (реже -- в ячейках памяти), относительно которого и ведётся адресация с помощью смещения, индекса, отклонения (тут термины разные в зависимости от архитектуры). Значения же в CS и прочих регистрах 8086 (и в реальном режиме для IA-32) не являются полными адресами, а лишь их частью, поэтому сегментная адресация 8086 не является полноценной относительной адресацией, хотя идея, в общем-то, та же самая. Кроме того, у сегментации и относительной адресации различается основная цель: первая придумана для того, чтобы на 16-разрядном процессоре иметь доступ к объёму памяти, превышающему 64 Кбайта, а вторая -- именно для адресации данных относительно некоего базового адреса.
Кстати говоря, использование в Винде регистра FS для доступа к TEB (или как там он называется -- забыл уже) -- это пример нестандартного использования возможностей процессора. Хотя FS, как и любой другой сегментный регистр, на IA-32 предназначен для разделения адресного пространства на независимые сегменты и обеспечения их защиты, в Винде FS работает как базовый, а не сегментный регистр. Понятно, что технически он всё равно остаётся сегментным, однако он лишь указывает на структуру данных, находящуюся внутри общего плоского адресного пространства процесса, к которой можно добраться и через DS, ES, SS и CS (т.е. сегментация и связанные с ней возможности защиты памяти не используются). В 64-разрядном режиме FS и GS уже официально объявлены дополнительными базовыми регистрами.
Что же касается удобства в плане организации защиты памяти и виртуальной памяти, то абсолютно однозначно удобнее страницы. Сегменты -- идиотская идея, не имеющая абсолютно никаких преимуществ, за исключением возможности точно указывать длину защищаемой области, ценность чего на практике равна нулю (поскольку может более-менее эффективно использоваться лишь при фиксированной карте памяти, иначе постоянно надо корректировать дескрипторы сегментов, а это может выполнять только система, иначе весь смысл защиты теряется, ну а это -- дикие накладные расходы даже без учёта необходимости постоянно перезагружать сегментные регистры). Недаром AMD, изобретая AMD64, выкинула сегментацию из 64-разрядного режима, после чего Intel без изменений скопировала это расширение архитектуры: всё равно этим маразмом никто на практике не пользовался. Страничный же механизм как появился в 1960-х, так и до сих пор успешно применяется в силу своей простоты в использовании, удобства реализации на уровне железа, низких накладных расходов. Отсутствие его в 80286 (да и в 8086, по большому счёту, тоже) объясняется не его сложностью или ещё чем, а абсолютной тупостью архитекторов Intel, проявившеся ещё при создании первых 8-разрядных микропроцессоров.
Ну и не следует считать, что сегменты во всех случаях -- это именно то, что называется сегментами в IA-32: надо всегда учитывать особенности использования терминологии тем или иным производителем, иначе может получиться фигня. Например, в мэйнфреймах IBM System/370 и последующих используются термины "сегмент" и "страница", однако тамошние сегменты -- это первый уровень механизма динамической переадресации (т.е. виртуальной памяти), а страницы -- второй уровень; первые имеют размер 64 Кбайта или 1 Мбайт, а вторые -- 2 или 4 Кбайта. Один из управляющих регистров тамошнего процессора содержит базовый адрес таблицы сегментов, а элементы таблицы сегментов содержат базовые адреса таблиц страниц. На IA-32 работа страничного механизма принципиально такая же, лишь уровней переадресации может быть и 2, и 3, и 4 в зависимости от разрядности физического адреса и размеров страниц; ну и терминология другая: таблицы страниц, каталоги страниц, ещё там что-то (уж не помню, а документацию лень смотреть). На ARM тоже своя терминология: первый уровень -- секции или суперсекции, второй -- страницы.
Сегментных регистров у ARM нет. С адресацией там в целом проще и удобней, особенно если сравнивать с 8086 и реальным режимом IA-32, поскольку в плане адресации все имеющиеся 16 регистров являются равноправными (ну а полностью равноправны в родной системе команд 13 из этих 16 регистров, ещё три имеют специальные функции). В 8086 же все восемь регистров "общего назначения" имеют специальные функции; в частности, в качестве базовых могут использоваться только BX и BP, что резко ограничивает возможности адресации. В IA-32 эти ограничения почти убрали, расширив систему команд и раздув кодировку, но всё равно уродств хватает (особенно в плане кодирования команд, что программист не очень видит, даже если пишет на ассемблере). У ARMов, правда, свои заскоки, связанные с системами команд Thumb и Thumb-2 -- там тоже архитекторы те ещё, хотя и не настолько шизанутые, как в Интеле...
|