Микропроцессор «из гаража»

    Наверняка каждый, имеющий дело с электроникой и ПЛИС, знаком с сайтом opencores.org, где собрано множество полезных (и не очень) решений для электроники — десятки, может быть и сотни, реализаций процессоров и периферии — как оригинальных реализаций уже существующих устройств, так и новых разработок. В этой статье пойдёт речь о 32-битном микропроцессоре с оригинальной системой команд, созданном на основе платы «Марсоход2».

    Наша команда в течение 10 лет занимается микроядром L4 и в какой-то момент пришло понимание, что само микроядро можно реализовать в виде блока процессора. Причём, если полноценное микроядро реализовать в «железе» весьма трудно, то можно хотя бы помочь программной части, переложив часть функций на железо. Сперва мы решили пойти по лёгкому и оптимальному пути — изучить существующие решения, выбрать подходящее и доработь напильником добавить возможности, полезные для микроядра. Работа заняла около месяца и былы изучены почти что все решения, найденные на opencores. Взятие за основу готового решения открывало неплохие возможости, в виде готовых компиляторов и различных библиотек. В какой-то момент нам перестали нравиться существующие решения — что-то оказалось сложным, что-то неоптимальным, что-то просто недоделанным, что-то, чего уж скрывать, имело не очень подходящую лицензию и условия использования. Набравшись смелости и скрипя зубами мы начали авантюру, решив разрабатывать процессор с самого начала.

    С чего начинается микропроцессор? Спросите у системного программиста, и он ответит вам что это система команд. Несмотря на тотальную моду на RISC архитектуру, мы решили не привязывать длину инструкций к размеру машинного слова. Поэтому мы провели несколько экспериментов. Как ни странно, но очень удобным инструментом для проектирования системы команд оказался… Microsoft Excel. Прежде всего мы выделили несколько столбцов, использовав их для нумерации инструкций в трёх системах исчисления — десятичной, шестнадцетричной и двоичной. В итоге получилось 256 строк, по числу состояний, которые можно описать одним байтом. Затем мы попытались логически сгруппировать инструкции таким образом, чтобы схема их декодирования была максимально проста. Первый блок инструкций заняли однобайтовые инструкции — префиксы, модификаторы и простые инструкции. Следующий блок инструкций выглядит так:

    image

    На следующем этапе пришлось определиться с количеством и типами регистров. Сколько регистров, по-вашему, будет оптимально для большинства задач? Ответы на этот вопрос могут сильно отличаться в зависимости от личности отвечающего — кому-то и 32-х нехватает, как есть и приверженцы безрегистровой архитектуры. Мы решили остановиться на 16-ти регистрах общего назначения. Это количество вполне комфортно для программирования на ассемблере, вполне удачно ложится на нашу архитектуру и несложно реализуются в HDL.

    Определившись с регистрами, мы решили сделать полностью позиционно независимую систему команд — в архитектуре нет ни одной команды перехода по абсолютному адресу — все переходы осуществляются относительно текущей команды. Мы просто помешаны на компактности, поэтому все команды переходов имеют три формы — знаковые смещения размерностью 1, 2 и 3 байта. Например, ниже показаны переходы с 16-битным смещением:

    image

    Наконец, мы отказались от понятия аппаратного стека, в пользу организации стека «по соглашению». Для этого был введён специальный префикс NOTCH и следующая схема — если перед инструкцией условного или безусловного перехода стоит этот префикс, то в регистр R15 помещается адрес следующей инструкции, т.е. адрес возврата. Соответственно, инструкция RETURN выполняет переход по содержимому регистра R15. Таким образом при вложенных вызовах подпрограмм, забота о сохранении адреса возврата ложится на программиста или компилятор. На первый взгляд это кажется не очень удобным, оптимальным и привычным, но если задуматься, то получается несколько преимуществ — во первых, можно сэкономить несколько тактов не сохраняя этот регистр во внешней памяти в терминальных подпрограммах (т.е.подпрограммах, которые не вызывают других подпрограмм), во вторых, префикс NOTCH можно поставить перед инструкцией условного перехода, тем самым реализовав условные вызовы функций — пусть и небольшая, но тоже экономия. Что касается сложности программрования на ассемблере, то их прячут макрокоманды, являющиеся ассемблерными мнемониками более высокого уровня.

    Позиционная независимость кода вносит ещё одну особенность — обращение к константным данным. Поскольку код может быть расположен по произвольному адресу, то и константные данные могут быть расположены произвольно вместе с кодом. Решение оказалось весьма простым — использование того же самого префикса NOTCH при загрузке в регистр константы, использует константу как смещение относительно исполняемой инструкции — таким образом решается проблема адресации данных в позиционно независимом коде.

    После проектирования системы команд, которое в целом заняло около года, мы вооружились средой Qauartus и Icarus Verilog и… поняли что поспешили. Реализовать систему команд на языке Verilog оказалось чертовски сложным. Знающие люди посоветовали обкатать решения на программной модели, написав декодер и другие функциональные устройства на обычном Си. После реализации эмулятора несуществующего процессора и прогона на нём тестовых программ — дела пошли лучше. Ещё полгода понадобились на реализацию процессора на Верилоге. Тут следует сказать, что для новичка программирование ПЛИС может оказаться невероятно сложным, а многолетний опыт программирования на языках высого уровня может даже усложнить задачу. В таком случае на помощь приходят средства моделирования. На первом этапе чрезвычайно полезным оказался Icarus Verilog — бесплатный инструмент для моделирования схем, в комплекте с которым идёт GTKWave — программа для отображения сигналов. Используя эти инструменты можно увидеть что происходит с устройством в каждый момент времени. На каком-то этапе возможностей Icarus Verilog стало мало и мы воспользовались симулятором ModelSim компании MentorGraphis — это очень мощный коммерческий инструмент, урезанную версию которого можно бесплатно установить совместно со средой Altera Quartus.

    О процессе отладки можно рассказывать долго. И вот в какой-то момент, когда ресурсы ПЛИС были заняты на целую треть, неожиданно появилось понимание, что полученный процессор уже можно использовать для каких-то проектов.



    Для демонстрации возможностей процессора мы написали простейшую микропрограмму, которая при старте выводит следующее меню на экране удалённого терминала:

    ┌────────────────────────> Welcome to Everest core <───────────────────────────┐
    │  1 - Load binary file via X-modem protocol                                   │
    │  2 - Run previously loaded binary file                                       │
    │  3 - Show RAM (0x100000-0x100140)                                            │
    │  4 - Test of message registers                                               │
    │  5 - Show previously loaded ANSI picture                                     │
    │  6 - Show built-in ANSI pic #1                                               │
    │  7 - Show built-in ANSI pic #2                                               │
    └──────────────────────────────────────────────────────────────────────────────┘
    


    Если нажать клавишу 1 и если ваш терминал поддерживает передачу файлов по протоколу X-modem, то в устройство можно загрузить файл размером до 4 Кб. Это может быть текст или ANSI-картинка — в этом случае нажатие на клавишу 5 выведет текст или картинку на экран. Но стоило бы ради этого писать статью? Конечно нет, поэтому при нажатии в терминале на клавишу 2 управление передаётся коду, загруженному с помощью первого пункта меню. Если передать управление загруженному тексту или ansi-картинке, то через несколько шагов процессор наткнётся на несуществующую (ещё неопределённую команду) или обратится к несуществующей памяти. При этом произойдёт переход процессора в пошаговый режим — каждый код, принятый с терминала, вызовет выполнение одной инструкции процессора с выводом состояния шин на удалённый терминал.

    image

    Самое время нажать клавишу «Сброс». Мы назвали «сбросом» левую кнопку на плате Марсоход2.

    Чтобы заставить устройство сделать что-нибудь осмысленное, вам понадобится Макро Ассемблер. В этот архив, помимо самого ассемблера и нескольких примеров, мы поместили исходный код микрокода процессора. Ниже показан пример простой пользовательской программы, которую можно с помощью ассемблера перевести в бинарный файл и загрузить в процессор.

    function   user_main
    	load	r14, 0x2000
    	push	r15
    loop:
    	call	_get_sysclock
    	load	r2, 0x05F5E100
    	call	_div64
    	call	_print_dec
    	lea	r1, $shw_str	
    	call	_puts		
    	call	_uart_status
    	rcr			r0, 2		; Бит RCV_RDY в перенос
    	jc			done		; Выход из цикла если была нажата клавиша
    	load	r0, 0x01000000
    	call	_delay
    	jmp	loop
    done:
    	pop	r15
    	return
    end
    
    include		tty.asm
    include		delay.asm
    include		mul.asm
    include		div.asm
    include		print_dec.asm
    include		sysclock.asm
    
    $shw_str	db	' seconds since boot',13,10,0
    


    Эта программа в цикле, до нажатия на любую клавишу в терминале, выводит в удалённый терминал информацию о количестве секунд с момента старта или сброса устройства. Чтобы проверить её в деле, понадобится сгенерированный файл usr_demo2.bin.

    Небольшое пояснение к программе. Подпрограмма _get_sysclock возвращает количество импульсов кварцевого генератора с момента включения или сброса устройства. Пример дампа подпрограммы:
    ; ------------------- _get_sysclock ------------------
    0198:   37 e3           ; DEC 	R14, 4 
    019a:   60 e3           ; MOV 	(R14), R3 
    019c:   e3 ff fe ff f8  ; LOAD 	R3, 0xfffefff8 
    01a1:   68 03           ; MOV 	R0, (R3) 
    01a3:   36 33           ; INC 	R3, 4 
    01a5:   68 13           ; MOV 	R1, (R3) 
    01a7:   68 3e           ; MOV 	R3, (R14) 
    01a9:   36 e3           ; INC 	R14, 4 
    01ab:   05              ; RETURN 
    


    При выходе из подпрограммы _get_sysclock регистр R0 содержит младшие 32 бита, а регистр R1 старшие 32-бита результата.
    Константа 0x05F5E100 это число импульсов тактового генератора за одну секунду.

    Скачать свежую версию прошивки для платы Марсоход2 можно по этой ссылке.

    Если вы не слышите новостей от нашего проекта, то знайте — мы работаем над переносом микроядра L4 в ПЛИС.
    Спасибо за внимание.

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 45

      +1
      Довольно интересно. Помню прошлым летом тоже решил заморочиться, попробовать для общего развития написать «свой процессор». Я правда тогда остановился на армовской системе команд, правда реализовал довольно ограниченное их количество. Только самое необходимое. Я так понял вам еще и свой компилятор пришлось писать из-за не стандартных команд? Меня на такой подвиг уже не хватило, не знаю как вы решились на такое, я честно говоря не вижу на первый взгляд у вашей системы команд особых преимуществ, чтобы тратить на нее столько времени. Использовали ли вы конвеер и скольки уровневый он получился? Что-то не нашел об этом упоминаний в тексте
        +2
        Коневейер пока не использовали. Есть некоторые идеи относительно конвейера, есть даже мысли об одновременном исполнении нескольких инструкций, поместившихся на 40-битную шину, но сейчас нам более интересно движение в сторону микроядра — довольно новая область, которой пока никто серьёзно не занимался.

        О преимуществах системы команд не готов спорить — в настоящий момент реализовано минимальное подмножество, достаточное для практического применения. Но в силу минимализма она проиграет по эффективности другим системам команд. Однако, система команд спроективроана так, что может быть безболезненно расширена. В принципе, система команд проектировалась с учётом двух требований — простота разбора и расширяемость.

        Наконец, что касается компилятора, то тут всё сложно — его научили лексическому и синтаксическому разбору, но до генерации кода руки не дошли. В общем, о компиляторе я пока не готов говорить — это половина компилятора. С другой стороны — есть несколько сторонних разработчиков, котрые пишут компиляторы. У нас есть взаимный интерес и при удачных обстоятельствах эти разрааботчики могли бы добавить поддержку нашего процессора в свои продукты.

          +5
          А вы не думали о том, что можно решить задачу написанием соответствующего кодогенератора для LLVM? Вы тогда ещё как минимум получите бесплатный компилятор для C/C++ в виде clang.
        +4
        Спасибо, статья реально вставила. Всячески залюсовал.
        Приятно что не перевелись в сети люди вроде Вас!
          +1
          По поводу регистров — IMHO стоит разделять адресные и арифметические регистры (как в MC68xxx и BlackFin). Во первых, это увеличивает число регистров без увеличения размера команд. Во вторых упрощает регистровые файлы и коммуникации.
          Про моделирование — я участвовал в проектах моделирования на SystemC и Haskell (даже без специальных библиотек). Haskell оказался практически идеальным языком для этого. Для C для разбора системы команд мы использовали The New Jersey Machine-Code Toolkit — поделка старая и не подерживаемая, но удобная и работающая. Если Haskell не устроит, может пригодится :-).

          А как у Вас с компилятором?
            0
            Пока только лексический и синтаксический анализаторы — генерации кода нет.
            +2
            Честно говоря даже немного завидно — такой героический труд проделан…
            С другой стороны, мне кажется нет особого смысла делать процессор, который принципиально не отличается от многих других подобных. Совсем другое дело — это сделать процессор принципиально иной архитектуры (вот сам все время думаю об этом).
            Не знаю точно, что можно подразумевать под принципиально «иной» архитектурой, но уверен, такие появятся, может быть уже скоро. Может быть это будут процессоры на лету меняющие архитектуру под конкретную задачу. Может быть это будут процессоры с какой-то нелинейной адресацией памяти. Может вместо памяти в компьютерной системе будут логические блоки и сама запись или чтение из памяти уже смогут выполнять некоторое действие…
            Кто придумает это «иное» и сможет сделать «это» популярным, тот и выиграет.
              +2
              Спасибо за статью.
              Идея интересная. Но вспомнился один иследовательский проект для военных. Там лозунг был, что можно некоторые функции ОС реализовать в железе. Предполагалось, что это позволит сделать более защищенную систему.
              В общем у нас товарищи разработали технологию HaSCol. И утверждали, что с помощью нее могут сделать процессор + компилятор за пару месяцев. В реальности все оказалось более прозаично. После первого года удалось сделать ядро процессора без периферии и gcc без оптимизации. Не было средств синхронизации, не были поддержаны даже прерывания, а некоторые вещи даже не в командах ассемблера приходилось писать, а их численным эквивалентом. С трудом удалось портировать маленькую собственную ОС Embox. В которой только shell показали (Заказчик хотел Linux). На следующем этапе удалось убедить разработчиков, что нужно использовать стандартную архитектуру, чтобы свой компилятор не писать. И с помощью этой технологии уже была разработана своя реализация процессора с архитектурой DLX, более известный как Microblaze от компании Xilinx. А уже в стандартной архитектуре сделали улучшения и какую то аппаратную поддержку ОС.

              Собсвенно вопрос, а какие именно части L4 вы собираетесь запихать в аппаратуру? Если все ядро, то как это будет выглядеть по вашему?
              Добавите в команды отправку сообщения и переключения контекста или будете это на микрокоде реализовывать?
                +1
                Прежде всего аппаратный планировщик и средства для переключения контекста. Для начала в едином адресном пространстве, без виртуальной памяти.

                Добавятся инструкции захвата и освобождения буфера сообщений. Добавится самая главная инструкция, ради которой всё это затвевлось — «Inter Process Communication». Пока что есть мысли реализовать эту инструкцию через микрокод. Видите, даже мненмонику ей ещё не придумали — аббревиатура IPC будет не очень удачной, поскольку среди электроников аббревиатура IPC имеет устоявшееся значеие «Instructions Per Cycle».

                Есть идея спрятать «удалённую сторону» за инструкцией обмена сообщениями — в общем случае задача, выполняющая обмен сообщениями, не должна знать и видеть разницу с кем она обменивается сообщениями — с другой задачей или с устройством. Если удастся реализовать такую прозрачность, то дальнейшее будущее проекта видится в радужном свете.

                Наконец, управление задачами и адресными пространствами планируется реализовать с помощью сообщений планировщику.

                Вот такие планы на будущее.

                  +2
                  Понятно.
                  По нашему опыту, очень большой прирост производительности давала аппаратная реализация MMU. Сравнивали реализации была на SPARC (Leon3) и Microblaze собственной разработки и оригинальная версия. Аппаратная поддержка таблиц при переключении контекстов которая есть в SPARC просто ни в какое сравнение не лезет с вариантами где есть только TLB. Но это для Линукс, где используются процессы.
                  Думаю, переключение контекста сделать довольно реально. А вот с IPC возможны большие проблемы, хотя если делать на микрокоде то можно получиться.
                  Вообще проект интересный! Удачи!
                +4
                Но стоило бы ради этого писать статью?
                Однозначно да.
                  +1
                  Такой объём работы и настолько крутые планы тянут на десяток статей.

                  Я однозначно хочу L4 в процессоре!
                  0
                  В какой-то момент нам перестали нравиться существующие решения — что-то оказалось сложным, что-то неоптимальным, что-то просто недоделанным, что-то, чего уж скрывать, имело не очень подходящую лицензию и условия использования.

                  Какая лицензия вам бы подошла? Какую лицензию планируете для конечного продукта?
                  Рассматривали ли вы коммерческие конфигурируемые процессоры, например xtensa или ARC?

                  Набравшись смелости и скрепя зубами мы начали авантюру, решив разрабатывать процессор с самого начала.

                  пойдёт речь о 32-битном микропроцессоре с оригинальной системой команд

                  32 бита — несколько странный выбор для процессора общего назначения в наше время.
                    +2
                    пойдёт речь о 32-битном микропроцессоре с оригинальной системой команд
                    32 бита — несколько странный выбор для процессора общего назначения в наше время.
                    Объясните пожалуйста, почему?
                      0
                      Потому что раньше (больше 10 лет назад :) 4Г памяти были либо недоступны, либо занимали много места. Сейчас даже встраиваемая мелочь идёт с гигабайтами на борту, не говоря уже о системах общего назначения. Если 32 бита — это «пробный шар», а дальше планируется расширение, тогда понятно. Если не планируется, то полезность данной разработки сильно падает.
                        0
                        32-битность не означает ограничение какой бы то ни было памяти четырьмя гигабайтами.
                          +2
                          Ну привет, а виртуальные адреса вы из чего делать будете, если не из регистров?
                            0
                            Ладно. Я сливаюсь — пошёл курить гугл. Но что-то мне подсказывает, что всё не так просто.
                              +3
                              Это не серверный процессор, для остального есть костыли типа PAE. Ячейки ПЛИС удовольствие дорогое.
                                0
                                Ячейки ПЛИС удовольствие дорогое.

                                А время разработчиков, стало быть, дешёвое?
                                  0
                                  дорогое, но не настолько, чтобы использовать какой-нибудь mips. Я полагаю, что здесь решается своя задача и 32 бита им хватит.
                                    0
                                    Как вы лихо всё поняли,
                                    Это не серверный процессор
                                    ,
                                    32 бита им хватит
                                    , я вот не вижу откуда это следует.
                                      +1
                                      cyclone3 и L4 соответственно
                            +3
                            Для начала нужно осилить 32 бита. Огромное кол-во микроконтроллеров на 32 битных ядрах ARM Cortex сейчас приходят на смену 8 битных контроллеров. Или вы хотите, чтобы они сразу замену х86-64 сделали сходу?
                              –2
                              Я (не великий, впрочем, специалист в проектировании процессоров) не вижу существенной разницы, разрабатывать 32-битный процессор или 64-битный. А зачем делать хуже, если можно сделать лучше? И, к тому же, для «поиграться и выкинуть»
                              мы просто помешаны на компактности, поэтому все команды переходов имеют три формы — знаковые смещения размерностью 1, 2 и 3 байта.
                              — тоже странно.
                                +3
                                Даже текущие 64 битные процессоры архитектуры х86-64 являются 32 битными с 64 битной надстройкой. Itanium, который полностью 64 битный уже давно вымирающий вид. 64 битные ядра пока не нужны рынку микроконтроллеров, там балом будут править 32 битные и ещё очень долго. Там ещё только идёт переход на 32 бита с 8 бит. Это огромный рынок носимой электроники и интернета вещей.
                                Например умные часы Сони и Самсунг используют 32битные ARM Cortex. Подавляющее большинство современных смартов на 32 битах.

                                К чему это я, 64 бита будет сделать сложнее, потребуется больше времени, места на чипе для логики и так далее. И это не требуется. Кроме того, в будущем архитектуру можно будет расширить. Если бы это была коммерческая оплачиваемая разработка с достаточным бюджетом, то конечно имело бы смысл рассмотреть, но у коммерции были бы свои чёткие цели. А так, ребята сами пилят и взлетать нужно не на боинге, а на цессне.
                                  +1
                                  Ваша мысль мне понятна.

                                  Даже текущие 64 битные процессоры архитектуры х86-64 являются 32 битными с 64 битной надстройкой. Itanium, который полностью 64 битный уже давно вымирающий вид.

                                  Да что ж вы всё на intel оглядываетесь, который тут ни к селу ни к городу? У них долгая история, намеренная обратная совместимость, они ещё и немного 16-битные изнутри. Вы этого же желаете Алексею и компании? За пределами Intel Architecture тоже, кстати, есть жизнь: POWERPC, S390x, SPARC.

                                  64 битные ядра пока не нужны рынку микроконтроллеров, там балом будут править 32 битные и ещё очень долго

                                  Вопрос — нужно ли там L4?
                                    0
                                    Да что ж вы всё на intel оглядываетесь


                                    У Itanium как раз нет обратной совместимости, если не считать эмуляцию х86. Остальные на рынке представлены весьма слабо в настоящих реалиях. PowerPC чтобы не заглохнуть теперь доступен для лицензирования. SPARC и остальные тоже редки. Это не рынок для L4. Тягаться с серверными процами после скольких лет разработки можно будет? А на Интел и АМД поскольку они главные разработчики массовых процессоров были. Теперь к ним подтянулись по полной программе ARM-ядра.

                                    Вопрос — нужно ли там L4?

                                    На ранке контроллеров нужны любые интересные решения. Их легче попробовать, меньше требований. Софт пишется индивидуально для проекта. Поморгать диодиками и порулить роботом вместо ардуинки на процессоре отечественной разработки. Круто же!

                                    Так что на рынке МК путь открыт, хотя и конкурентов тьма, но они вообще продают системы на ПЛИС. Это курорт для разработчика процессоров.

                                    А вот на рынок PowerPC, SPARC и иже с ними, им не в путь, там без мощной инфраструктуры делать нечего со своей новой архитектурой.
                          0
                          Я с вами согласен, что для процессора общего назначения 32 бита маловато. Но для концепта или под встроенные системы вполне приемлемо. ARM-ы 64 разрядные только начали появляться, а 32 разрядные вовсю используются. Тут, как мне кажется, речь вряд ли идет о масс продакшен.
                          +1
                          в архитектуре нет ни одной команды перехода по абсолютному адресу — все переходы осуществляются относительно текущей команды

                          А как же «перейти по адресу в регистре» (частным случаем которой является return)? Или у вас такой команды нет? А как у вас виртуальные функции работают?
                            0
                            Есть такой процессор Z80. Он хоть и восьмибитный, но у него есть некоторые средства работы с 16-битными числами, ну и шина адреса тоже 16-битная. Может быть, подобным образом можно сделать 64-битную шину адреса у 32-битного процессора и тем самым решить вопрос с размерами линейного адресного пространства, который не дает покоя многим комментаторам.

                            Что же касается скорости работы — то на сегодняшний день многие 32-битные приложения на архитектуре x86 работают быстрее, чем 64-битные, из-за проблем с плотностью 64-битного кода. Потому что узкое место в скорости работы таких приложений — это не разрядность обрабатываемых чисел или количество регистров, а размер кэша и скорость доступа к памяти команд.
                              +1
                              Есть такой процессор Z80. Он хоть и восьмибитный, но у него есть некоторые средства работы с 16-битными числами, ну и шина адреса тоже 16-битная. Может быть, подобным образом можно сделать 64-битную шину адреса у 32-битного процессора и тем самым решить вопрос с размерами линейного адресного пространства, который не дает покоя многим комментаторам.
                              — Вы только что изобрели PAE.
                              проблем с плотностью 64-битного кода
                              — А плотность 64-битного кода плохая не потому, что он 64-битный (спасибо относительным адресам, абсолютные 64-битные не поддерживаются в x86-64), а потому, что у AMD руки и ноги растут из одного места.
                                0
                                Вы только что изобрели PAE

                                Нет, это не PAE. PAE появилось в 1995г и только в контексте процессоров IA-32. К тому же, PAE не увеличивает линейное адресное пространство сверх 32 бит. Описанное мною явление возникло гораздо раньше. Практически все 8-битные процессоры и контроллеры имеют 16-разрядную шину адреса и линейное 16-битное адресное пространство. Также характерны 16-битные операции со стеком адресов возврата. Адреса вызовов и переходов 16-битные, также обычно имеются какие-то возможности косвенных переходов по адресам, хранящимся в паре регистров. Именно в Z80 объединение 8-битных регистров в 16-битные пары реализовано наиболее развито.

                                И все это при том, что процессоры формально 8-битные. Они имеют 8-битное АЛУ и, таким образом, одновременно обрабатывают только 8 бит информации.
                                А плотность 64-битного кода плохая не потому, что он 64-битный

                                Ну, даже если оптимизировать систему команд 64-битного процессора, все равно плотность кода обязательно уменьшится по сравнению с таким же, но 32-битным процессором. Как минимум, вырастет размер адресов абсолютных переходов, если мы хотим сохранить линейное адресное пространство. Если же нет — то потребуются пляски с бубном для организации страничной и т.п. адресации, что опять-таки выльется в раздувание размеров программы.

                                Хотя те же проблемы с плотностью кода появятся в случае реализации 64-битного адресного пространства на 32-битном процессоре.
                                  0
                                  Вы говорите не о линейном, а о логическом АП. Но логическое АП больше максимального машинного слова — не очень удобно. А в принципе, большинство существующих ОС для IA-32e работают именно так, по модели LP64: integerы 32 бита. Но это — одна из причин низкой плотности кода (спасибо префиксам).
                                    0
                                    Я говорю именно о линейном АП, когда все указатели имеют одинаковый размер. Противоположные случаи — страничная и сегментная адресация, при этом существует два вида указателей — near и far, которые имеют разную длину. И даже в случае PAE адресное пространство одного процесса и объем доступной ему памяти не превышает 2^32.
                                      0
                                      Когда АП больше машинного слова — это, конечно, создает некоторые неудобства. Но еще хуже, если АП имеет недостаточный размер. Тут просто выбирается меньшее из двух зол.
                                +1
                                Определившись с регистрами, мы решили сделать полностью позиционно независимую систему команд — в архитектуре нет ни одной команды перехода по абсолютному адресу
                                а RETURN это не команда что ли?) Производит переход по абсолютному адресу в R15
                                  0
                                  Вообще эта идея сделать любой код полностью релоцируемым — она ведет к затратам. Нужны сумматоры для вычисления адресов перехода, которые можно было бы выкинуть. И, как вы верно заметили, все равно трудно добиться, чтобы любой код был релоцируемым. С другой стороны, проблемы релокации уже давно и успешно решаются программно. Есть исполняемый файл, в нем есть таблица релокации. При загрузке файла происходит настройка его на адрес — и все. А для чего еще нужен релоцируемый код?
                                    0
                                    При загрузке файла происходит настройка его на адрес

                                    Вот в этом месте и ведутся основные бои в библиотеках С и их динамических линковщиках: как сделать так, чтобы код был и релоцируемым, и разделяемым, т.е. чтобы несколько приложений, загрузивших одну динамическую библиотеку использовали минимальное количество физической памяти. Каждая релокация — это изменение кода или данных, каждый процесс, изменяющий общую страницу получает свою изменённую копию. Если большинство вызовов/переходов — относительные, то релокации им не нужны. Для вызовов, которые точно потребуют модификации, например вызовов между разными библиотеками, применяются специальные техники, например PLT (procedure linkage table), группирующие данные изменяемые релокациями.
                                      0
                                      Если среди вызовов/переходов попадаются абсолютные — то настройка кода на адрес все равно нужна. Какая при этом разница, сколько нужно изменений? Главное — что невозможно полностью избавиться от них и присущих им проблем.

                                      В случае разделяемого кода в динамических библиотеках — из соображений безопасности с недавних пор ОС грузит библиотеки по случайным адресам для разных процессов, чтобы затруднить эксплуатацию уязвимостей. Этот подход делает фактически невозможной какую-либо экономию памяти за счет динамических библиотек.

                                      Также, помимо вызовов/переходов, существует проблема релокации данных. В данных могут содержаться указатели, которые требуют настройки на адрес.
                                        0
                                        Какая при этом разница, сколько нужно изменений?

                                        Большая: либо изменение каждой страницы, в которой есть такой вызов (при наивной реализации), либо изменение только страниц PLT, в которых собраны все такие переходы/вызовы (при использовании PLT). Т.е. в первом случае 256 вызовов раскиданных по 256 разным страницам — это +256 приватных страниц процесса, а во втором — +1 приватная страница (при размере элемента PLT в 16 байт).

                                        Этот подход делает фактически невозможной какую-либо экономию памяти за счет динамических библиотек

                                        Но не в случае относительной адресации данных/относительных переходов.

                                        существует проблема релокации данных

                                        Их тоже группируют по секциям: нуждающиеся в релокациях/не нуждающиеся.
                                          +1
                                          DLL — это веский аргумент.

                                          Идея заключается в том, что программе в общем случае не нужно знать адрес библиотеки для передачи ей управления. Программа обменивается сообщениями, при этом не происходит явной передачи управления. Соответственно, вместо адреса точки входа в библиотечную функцию, вызвающей программе необходимо знать ID задачи и ID запроса. При этом нет разницы, где расположена библиотечная функция — в соседнем потоке, на другом ядре или вообще, реализована аппаратно.

                                      0
                                      В системе команд нет инструкций, в которых явно указан абсолютный адреса перехода. Да, неудобно получилось — можно понять двусмысленно.
                                      +1
                                      Вопрос, — данное устройство предназначено исключительно для выполнения микроядра, или системные сервисы / пользовательские процессы будут выполняться на нём же?
                                        +1
                                        Системные сервисы / пользовательские процессы будут выполняться на нём же. Малое количество ОЗУ в этой прошивке объясняется тем, что используется только внутренняя память ПЛИС, а внешнее ОЗУ ещё не задействовано.

                                      Only users with full accounts can post comments. Log in, please.