Эзотерический поискФорумСобрание фантазий

CLŒVER

#0
8:16, 24 апр 2014

Clœver

От Автора

+ От Автора

Вступление

+ Introduction


Известно, что в процессорах Intel порты - костыли, чтобы компенсировать недостатоток, некогда, дифицитного адресного пространства. Сейчас, по-видимому, от этих пережитков избавились...
Как-то я подумал, что хорошо ведь придумали, что часть кода x86 (ESC) отдали под нужды сопроцессора (x87). Но, это было раньше. Сейчас это - де-факто. Так, ничего особенного (начиная с i80486)...
Я не раз делал попытки разработать систему команд, где каждое внешнее устройство, будь то ПДП или видеокарта, проецируется первым делом в систему команд. Т.е. когда процессор встречает незнакомую ему инструкцию, он даёт возможность обработать её другим устройствам. Включая и особенности указания векторов памяти, как в FPU-x87...

Выглядить это может примерно так (на примере с x86): Некоторые сегменты памяти объявляются как содержащие исполняемый код чуждой системы. Например, Java-машины или OpenCL. Тогда, когда инструкция CALL перейдёт в область того кода, процессор, вместо того, чтобы выполнять "бредо-код", укажет нужной "железяке" на необходимость выполнения тех инструкций.
Знаю, что это легко организовать с помощью исключений и других трюков. Но моя речь о том, чтобы сама система команд процессора включала бы возможность внедрения инструкций иного устройства.



Я не могу этого доказать и придётся верить мне на слово. Но ещё в 90-х, когда я знал о DOS лишь по справочнику, не говоря о Windows.
В голову пришла идея процессорной системы, где нижние 4Гб памяти выделяется под каждый процесс индивидуально. А остальные верхние адреса после 4Гб доступны как общие ресурсы.
0x0000000000..0x00FFFFFFFF: Память приложения
0x0100000000..0x01FFFFFFFF: Буфер консоли (терминал: клавиатура, дисплей, принтер)
0x0200000000..0x02FFFFFFFF: Буфер транзакций (сетевые транзакции; файловая система; межпроцессные; межпроцессорные)
...
Причём, система команд разрабатывалась так, чтобы все операции с данными структурировались. Код программы разбивался на объявления разных блоков на арифметику, транзакции и остальное. И в пределах блока инструкции выполнялись сопроцессором. Сопроцессоров много:
FPU: Арифметический процессор. Аналогия с x87. Но команды иные;
GPU: Графический процессор. В 90-е, когда я занимался этим, протокол графики ограничивался линиями, эллипсами и спрайтами;
SPU: Звуковой процессор. Компьютер ZX-Spectrum-128 с чипом Yamaha должен был выполнять его функцию;
WPU: Сетевой процессор. Компьютер с доступом в интернет...
Как видно, в моём случае я пытался сформулировать компьютерную систему, где центральный процессор относительно прост, но к нему подключаются очень много других процессоров (Z80, i8086, M68000), программы которых заточены под свой профиль.
Теперь я понимаю, что это относительно легко организовать в любой операционке...

Как человек, достаточно хорошо владеющий основами программирования машинного кода x86 могу заметить, что техника программирования на низком уровне ничем не отличается от языков программирования высокого уровня, таких как классические Fortran и Basic: Куча GOTO и GOSUB. Потому что, несмотря на то, что за прошедшие десятилетия частота процессоров возрасла на три порядка (от единиц мГц до нескольких гГц), технология построения программ не изменилась: Как был дамп инструкций, так он и остался...
Потому, если программа совершает переход на непредвиденный вектор, происходит сбой.

Первой попыткой была разработка системы команд, где подпрограммы объявляются явно и вызов их происходит не переходом по их адресу, а обращение к процедуре с известным идентификатором. Т.е. программа разбивалась на 4096 подпрограмм, которые также разбивались на 4096 субподпрограмм и т.д. Заранее строились таблицы с векторами на нужные процедуры. Как бы в x86 инструкция INT 0..255, но с использованием множества локальных таблиц.
Второй попыткой была организация системы команд, где наиболее редкие инструкции имеют более длинный код или составляются из отдельных команд (RISC?)...
Никаких CALL/JMP/RET, вместо которых - извлечение вектора из таблицы, занесение в стек и перенос в указатель инструкций. Причём, нет явного отличия трюка CALL и JMP. При переходе на новый вектор в стек адрес возврата не заносится. Для этого указатель инструкций IP имеет не 32 бита, а 256. И при переходе на иной адрес биты сдвигаются влево на 32 позиции. При возврате - вправо. Т.е. можно произвести до 6 вложенных вызовов и вернуться обратно. А старшие биты (32..255) в стеке должна сохранять сама подпрограмма.
Причём старшие биты (224..255) содержат вектор на обработчик исключений. И если совершить тупо 8 возвратов, управление получит системный код...

Эзотерический поискФорумСобрание фантазий

Тема в архиве.