Как показывает многократная практика дискуссий на эту тему, многие в упор не понимают, что мною имеется ввиду. И приходится идти на всяческие ухищрения, чтобы всё стало простым и доходчивым.
И в этот раз я попытаюсь вернуться к этому вопросу, но с несколько другого ракурса на примере DOS.
Для начала, сравните два кода:
Видно, что вторая версия не использует никаких вызовов системных функций и под них не нужно резервировать ни байта системного кода. Программа может иметь в своём распоряжении до 1 Мб памяти, так как и BIOS, как таковой, находится в теневой странице памяти. В этом примере прикладная программа не нуждается ни в каком системном коде, так как нужно просто программировать порты.
Плюсы: Если вы когда-нибудь программировали на Бейсике, то могли сталкиваться с ситуацией, когда необходимо было обратиться к функции DOS-API через USR. Необходимо было верно выбрать сегмент памяти под POKE, которыми записывался машинный код. Туда же вписывались и все нужные параметры. В общем, программисту-новичку приходилось не очень сладко, так как с высокого уровня необходимо было спуститься на самый элементарный уровень!
А если бы существовала аппаратная DOS-машина, на уровне Бейсика достаточно было оператором OUT и функцией IN обратиться к портам и всё. Никаких POKE и USR! Всё на достаточно высоком уровне остаётся.
Минусы:
- Необходимо довольно умное и дорогое железо, чтобы обрабатывать обращения ко всем прописанным портам на высоком уровне. Как вариант - карточка с дополнительным сервис-процессором, отдельной памятью ОЗУ и ПЗУ под всё функциональное API
- Либо необходим, как минимум, процессор i286, где уже имелись нормальные механизмы защиты памяти и портов ввода-вывода. Лучше, конечно, процессор i386 с полной виртуализацией памяти и портов. Через механизмы исключений система просто определяет, к какому порту приложение пыталось вести доступ и просто исполняет высокоуровневую функцию
- Обращение к портам ввода-вывода занимает относительно много машинного времени по тактам. Однако, учитывая, что приложение обращается не к каким-то там элементарным периферийным регистрам, а программирует DOS-операции высокого уровня, то по скорости обращение к порту будет не хуже классического call/int вызова
Если бы в своё время с появлением i286 сама DOS совершила бы «квантовый скачок» и перешла бы на уровень аппаратной виртуализации своего функционала, то и Windows могла бы полностью уйти на тот же уровень…
При этом, необходимость в верхних 2 Гб памяти под системное API полностью отпала бы. Приложению можно предоставить все 4 Гб адресного пространства, так как вместо загрузки системных библиотек, код которых нам не доступен на чтение и не так важен, ведь он просто засоряет где-то адресное пространство и нужен лишь для call-вызовов.
Вместо этого, имелись бы порты ввода-вывода под такие высокие уровни, как OpenAL, OpenGL, DirectSound, DirectPlay, DirectInput, GDI и т.д.
Никаких подгружаемых системных библиотек. Только порты.
При этом, даже сам DOS формата *.com мог бы несколькими строчками ассемблера запрограммировать порт окна и OpenGL, выведя туда 3D-сферу. То есть, вместо кривой виртуализации DOS-машины, мы бы имели бы эволюционное развитие DOS-программ под Windows-среду.
P.S.: А что мы получили?
У Linux - int 80h, у Windows - int 2Eh…
А как итог, *.com файлы на современной системе вообще не поддерживаются.