Там есть так называемый защищённый режим, унаследованный от советского Эльбруса. В СССР эта защита в железе дополняла защиту в софте. Несмотря на то, что Паскаль и Си ровесники (1970), пока стоял СССР, в страну Си не пускали, зато очень заинтересовались Адой, приняли ГОСТ, перевели книги, написали с десяток трансляторов, в том числе под Эльбрус. И там была гармония между семантикой языка программирования и железом.
По прошествии лихих годин (выражение Ельцина, 1992 год) потенциал был растрачен, и былая гармония раскололась. Эльбрус выжил, но трансляторы для него теперь совсем другие, главным образом это Си (C++ там был куплен у Edison group, которые делают Comeau C++-> C транслятор). Си не создавался в расчёте на безопасность, это, по выражению создателей, переносимый ассемблер, но вот на этот ассемблер попытались навинтить унаследованную от советского Эльбруса аппаратную защиту. Если в случае с Адой железо органично продолжает воплощение языковых запретов, то для Си навинчивание защиты является хаком, и для многих программ на Си, особенно, где местечковое ООП реализовано, или хоть немного шаг влево, шаг вправо, всё, такая программа уже не транслируется без допиливаний. Так что если взять купить Эльбрус, там практически ничего не работает в защищённом режиме, он там где-то сбоку есть. В презентации МЦСТ про защищённый режим был описан программный комплекс из Эльбрус полностью в защищённом режиме и обычного ПК с Windows 10. В защищённом режиме не было графического режима, потому что даже примитивные библиотеки для фреймбуфера не портированы. Отображение было на Windows 10 по сети. Часть кода зачем-то пришлось портировать с C++ на C.
Механизм защиты строится на том, что в дополнение к значащим битам информации есть биты тегов. В оперативной памяти они хранятся в битах ECC, вместо битов контроля ошибок аппаратных сбоев. Из памяти теги перетекают в регистры. Обращаться к памяти из защищённого режима можно только по дескриптору. Дескриптор должен иметь подходящий тег. Если тега нет, то это просто число, которым никак иначе нельзя воспользоваться. Любые неправильные операции над дескрипторами либо возбуждают исключение, либо ломают тег, превращая дескриптор в число.
Дескриптор состоит из нескольких указателей и служебной информации. В служебную информацию входит дескриптор модуля. Можно ограничить, какой модуль может работать с конкретной структурой данных. То есть, какой-то другой модуль может получить указатель на чужую структуру данных, но она будет как чёрный ящик. Например, если в этой структуре лежат два числа, то чтобы прочитать эти числа, нужно из указателя на структуру данных получить валидный дескриптор на первое или второе число, а потом прочитать содержимое нового указателя. Система межмодульной защиты не даёт чужому модулю сделать такое преобразование. Значит, в обход нужного модуля ни читать, ни писать внутрь нельзя. Впрочем, операции с численным представлением дескриптора доступны. Например, если есть какой-то другой указатель, можно, сравнивая численные представления, узнать, находится ли содержимое по указателю внутри этой структуры или нет.
Дескрипторы данных образуют двухуровневую модель. Для разных уровней два разных типа дескриптора. В общем случае какая-то (двухуровневая) структура данных — это массив из экземпляров классов. У массивного дескриптора есть текущий элемент, и есть границы массива. Текущий элемент по правилам языка Си может быть за границами. Для промежуточных вычислений нормально, а для разыменования — нет. Для массивного дескриптора работает адресная арифметика. Но размер элементов фиксирован.
Каждый элемент массива в общем случае какой-то экземпляр класса, и описывается объектным дескриптором, в котором вместо границ массива другие указатели, нужные для реализации ООП. Конечно, полем объекта может быть массив, и получается такая вот матрёшка. Особую роль играет операционная система и рантайм библиотека. Процессор не такой уж умный, и отнюдь не любые правила преобразования дескрипторов зашиты в его железо. Многие операции на самом деле выполняются в рантайм библиотеке, которая наделена для этого дополнительными привилегиями. Она-то и знает про то, какие в модулях есть типы, и как, и кому можно преобразовывать дескрипторы.
Также в Эльбрус есть способ пометить память как неинициализирванную для отлова ошибок обращения к ней.
Наконец, для данных на стеке есть ещё индекс кадра стека, так что разыменовать дескриптор на кадр стека вернувшейся функции не получится. Эта ошибка тоже будет поймана.
Подводя итоги, дескриптор содержит:
1. обычный указатель
2. тип дескриптора (массивный/объектный)
3. дескриптор модуля
4. индекс кадра стека
5. либо указатели на границы массива, либо указатели на информацию для ООП
1 и 5 дают как минимум 3 обычных указателя в одном дескрипторе, а 2-4 добивают дескриптор информацией под завязку. Известно, что размер дескриптора 128 бит. По всему видно, что как ни крути, а 3 64битных указателя, хоть их до 48 бит обрезай, ну не влезают никак. Может, 36 бит ещё можно впихнуть, но, похоже, что нет. Так что защищённый режим Эльбруса 32битный или не сильно отличается от такового.
Впрочем, незащищённый режим тоже защищён чуть посильнее, чем на других процессорах. В незащищённом режиме чуть более, чем обычно, защищён стек.
По большому счёту, многие ошибки, от которых даёт защиту Эльбрус, специфичны для C и C++. Программисты на С и С++ создают проблемы, и тут появляется Эльбрус и типа их героически решает. Ну это бред, если так подумать. По-хорошему, надо писать на Аде и от других требовать того же. Сколько лет существуют ошибки переполнения буфера, столько же лет существует и решение для них (Паскаль и Си ровесники). Учитывая, что в защищённом режиме Эльбрус почти ничего сишное просто так не работает, выходит, что под Эльбрус писать новый софт на Си, что на Аде, ощутимые вложения труда делать хоть как придётся. Но на Аде оно будет защищено везде, не только лишь на Эльбрусе, и на Аде есть 64 бита. А для повышенной защиты есть верифицируемое подмножество SPARK, которое в последнее время переживает бум. Раньше SPARK был довольно дубовый. Если что-то нельзя верифицировать, то в SPARK этого не было. Например, там не было обычных контейнеров, как в языке Ада, а были свои, занимащие сразу максимальный размер памяти. Но сейчас готовится заимствование из ParaSail и Rust безопасных указателей, так что с динамической памятью в SPARK станет посвободнее.
Аппаратная защита в Эльбрусе не уникальна. Был когда-то Intel i960MX. На базе MIPS в Кембридже разработали CHERI, и он и сейчас продаётся. В отличие от Эльбруса, там не секретничают. Можно прямо с сайта скачать эмулятор, документацию и инструменты разработки. Бери, смотри, изучай кто хочешь. И это не Россия под санкциями, это влиятельный британский университет. Ничего из этого не помогло ему занять какие-то особо значимые ниши. Верификация не имеет 1:1 соответствия с аппаратным контролем, им бы лучше дополнять друг друга, чем заставлять выбирать, но видно, что реальные покупатели, авиация (Боинг), а с некоторых пор беспилотные автомобили (nVidia) полагаются на верификацию больше, чем на аппаратную защиту.