q2e74, Вaм стоит перечитать мои тему здесь и тему там, где я довольно развёрнуто многие моменты рассматривал концептуально. Например, ту же полимерную память. В моей концепции одна инструкция in/out может отнять миллиарды тактов и прикладной код будет простаивать. Вас это может, наверное, сильно озадачить. Но на эту сторону концепции следует посмотреть под другим углом. В DOS «INT 10h» передаёт управление драйверу терминала и программно в отладчике, в отличии от call, как будто никуда не прыгает. Будто бы «int»-инструкции - это гиперсложные операции, требующие миллиарды тактов… Везде в документациях инструкции in/out описываются как «плохие» из-за их медлительности. Я же прикинул, что те же «GetDC» или «SendMessage» WinAPI тоже останавливают исполнение прикладного кода и уходят куда-то в теневую зону DLL. То есть, хоть логически приложение и прыгает в регион DLL для выполнения системного кода, но формально приложение долго стоит, достаточно перед тем же «GetDC» и после него врезать «asm rdtsc» и подсчитать такты, пока наш код, грубо говоря, стоял… Потому с самого начала мною концептуально заявлялось, что любая «in/out/ins/outs» инструкция может потребовать миллиарды тактов… И многие сразу сказали, что это - не правильно и система, значит, очень плохая! P.S.: Надеюсь, теперь-то видны ключевые моменты, где привычное «очень плохо» местами вызывает «вау-эффект»?
именно так. и не догоняю, допустим вы реализовали операционную среду, у вас всё получилось. Как проц делит время между процессами? кто орбитр? какой-то полиморфизм в масштабах ос. как возвращаться в исходное состояние после деинсталляции пакета? тем более, когда эти приложения уже накрутили содержимое памяти в мегафарш?
Eсли интерес к моей концепции всё ещё имеется, то рассмотрим ещё одну мою мысль… Ещё 30 лет назад у PC была актуальна тема музыкального Adlib-синтеза с FM-эффектами карточками OPL-SA3. При помощи программирования регистров можно было добиться различных эффектов. Значительно позднее я задумался, а почему, наряду с синтезаторами музыки и голоса, не существуют синтезаторов графических сцен? То есть сцены на экране состоят из конкретных спрайтов и по-существу являются сэмплерными, так как спрайты заранее подготовлены. В то же время синтезом можно было бы в кадре генерировать дождь или снег на аппаратном уровне. Как это всё должно выглядить? В NES у 6502 нижние 256 байтов нулевой страницы в играх активно используются и легко поддаются хаку, например, когда необходимо пройти сквозь стену: Достаточно отследить ячейку, хранящую горизонтальную позицию персонажа, чтобы вписать туда нужное значение и совершить «телепортацию»… Тем самым, если очень сильно утрировать, то вместо того же X-Box можно в консоли иметь всё тот же старый добрый 6502 и его нулевую страницу в режиме реального времени отправлять в Облако. А Облако, по видеоканалу будет возвращать результат рендеринга сцены своим синтезатором. Программисты поймут, что каждая из сотен NES-игр имеет собственный отпечаток активности в нулевой странице. Тем самым, сервер может распарсить все 256 байт во времени и автоматически распознать игру, загружая под неё готовый шаблон, но с «плюшками XXI века», где и Марио в 3D и Танки от первого лица… Но это получится просто эмулятор. А я говорю про Синтезатор Сцен… Допустим, программа «Регистры Погоды» загружает флажками и значениями дождливого вечера… Нейросеть должна либо в интернете найти видео с дождём, либо сама нарисовать тематический кадр, типа: Дальше, программа «Регистры Пейзажа» загружает флажками руин времён античности… Нейросеть находит тематические фотографии и накладывает их на фон, примерно вот так: Теперь уже можно отрисовывать батальную сцену активными персонажами. Как же должен выглядить дамп под весь этот синтез? Допустим, один из вариантов таков: Spoiler Code (Text): ADDR .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F +000 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки общего уровня играющего - позиционирование +010 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки 1-го уровня играющего - мастерство +020 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки 2-го уровня играющего - экипировка +030 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки 3-го уровня играющего - достаток +040 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки 4-го уровня играющего - движимое имущество +050 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки 5-го уровня играющего - недвижимое имущество +060 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки 6-го уровня играющего - повелитель +070 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки 7-го уровня играющего - властелин +080 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки 8-го уровня играющего - магистр +090 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки 9-го уровня играющего - маг +0A0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки «Animals»: Птицы, животные, жучки, рыбки… +0B0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки «Builds»: Пещеры, хижины, избы, дома, небоскрёбы… +0C0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки «Clouds»: Облака, осадки, небо, звёзды, солнце… +0D0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки «Disasters»: Ветра, ураганы, наводнения, землетрясения, звездопад… +0E0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки «Environment»: Туман, трава, деревья, речки, мосты, шоссе, Ж/Д, люки… +0F0 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ; Ячейки «Figures» - ключевые предметы или фигуры… И это всё! Этих 256 ячеек вполне достаточно, чтобы синтезировать сцену. Будете 100 раз запускать игру, будете видеть 100 разных вариантов одного и того же уровня, так как нейросеть умеет обучаться и фантазировать. А значит, не нужны никакие спрайты. Всё генерируется на лету. Главное Если Вы честно следовали за ходом моих мыслей, то уже должны понимать, почему в моей концепции Операционной Системы не предусматривается нативного API: Он там и не нужен… В Системе, где есть регистр с флажком «Падал Прошлогодний Снег» не нужны никакие функции с открытием файлов, сокетов и рисования линий… Приложение не нуждается в никаких системных библиотеках явно, так как просто через порты программирует Погоду и т.д. Например, такое реализовывается уже в наши дни А те же OpenGL/WebGL никак не могут шагнуть в новую эру и перейти на абстрактный объектный уровень. Нет, я ничего против DirectX и OpenGL не говорю. Но пора уже догонять морально реалии технологий, а не топтаться на уровне API 90-х. То есть, нужен, как минимум, реально новый движок, где не нужны текстуры или модели персонажей, так как всё должна синтезировать нейросеть. И тогда, на том же 6502, а лучше - на z80, можно будет снова писать код игр, по графике не уступающие любым современным платформам. P.S.: Процессоры видеокарт давно обошли центральные процессоры ПК. А морально те же API Windows и Linux не так далеко ушли из своих 70-х… Всё устарело вдоль и поперёк. Хотя та же видеокарта шейдерами может воспроизвести больше, чем сам центральный процессор. То есть, рано списали 6502, z80 или 68000. Если им предоставить вменяемое аппаратное оснащение, то программированием портов можно сделать буквально всё. Главное, чтобы вместо дурацкого порта HDD был порт, например, погоды! :lol:
да, теперь я понял свою ошибку, что windows 10, что linux, имеют серъёзные проблемы с безопасностью...
q2e74, Вoт здесь «CVE-2013-3198 (write-what-where в nt!VdmCallStringIoHandlerPushException)» пишут, что… Тем самым, из-под Windows-консольного приложения получится ли заиметь доступ к несуществующим портам, если запустить их эмулятор? Для запуска приложений Linux в Windows необходим libcurl.dll. Для запуска некоторых приложений DOS требовался DOS/4GW. Тем самым, задача состоит в том, чтобы написать собственный диспетчер портов ввода-вывода. Диспетчер должен заблокировать доступ ко всем (абсолютно) портам, даже если в Windows некоторые из них разрешены. Диспетчер должен пропускать обработку любых портовых операций нашего приложения через себя. Таким образом, все 65536 портов можно будет полностью виртуализировать под мою концепцию операционной среды. А если во время обработки исключений читать не просто DX, а весь EDX, то и портов станет 4 млрд. (В 64-битной системе с RDX можно, страшно представить, развернуть гектарные поля триллионов портов!) Как Вы уже можете понимать, в первую очередь необходимы порты «Погоды» и «Ветра»… Тем самым, данные от всех датчиков температуры и куллеров системного блока необходимо сконцентрировать в одну группу портов. Тогда, вместо гадкого MSAcpi_ThermalZoneTemperature и кучи кода, типа Spoiler Code (Text): HRESULT GetCpuTemperature(LPLONG pTemperature) { if (pTemperature == NULL) return E_INVALIDARG; *pTemperature = -1; HRESULT ci = CoInitialize(NULL); HRESULT hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); if (SUCCEEDED(hr)) { IWbemLocator *pLocator; hr = CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLocator); if (SUCCEEDED(hr)) { IWbemServices *pServices; BSTR ns = SysAllocString(L"root\\WMI"); hr = pLocator->ConnectServer(ns, NULL, NULL, NULL, 0, NULL, NULL, &pServices); pLocator->Release(); SysFreeString(ns); if (SUCCEEDED(hr)) { BSTR query = SysAllocString(L"SELECT * FROM MSAcpi_ThermalZoneTemperature"); BSTR wql = SysAllocString(L"WQL"); IEnumWbemClassObject *pEnum; hr = pServices->ExecQuery(wql, query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum); SysFreeString(wql); SysFreeString(query); pServices->Release(); if (SUCCEEDED(hr)) { IWbemClassObject *pObject; ULONG returned; hr = pEnum->Next(WBEM_INFINITE, 1, &pObject, &returned); pEnum->Release(); if (SUCCEEDED(hr)) { BSTR temp = SysAllocString(L"CurrentTemperature"); VARIANT v; VariantInit(&v); hr = pObject->Get(temp, 0, &v, NULL, NULL); pObject->Release(); SysFreeString(temp); if (SUCCEEDED(hr)) { *pTemperature = V_I4(&v); } VariantClear(&v); } } } if (ci == S_OK) { CoUninitialize(); } } } return hr; } достаточно использовать «__asm in al,dx», где в EDX (не просто в DX) индекс нашего виртуального порта из 4 млрд… Что бы я хотел сделать… То есть, не обязательно мою концепцию операционной системы писать с нуля, начиная с загрузчика ядра. Можно просто под Windows и Linux написать оболочки, где код будет работать без эмуляции, но в песочнице с кучей портов.
ошибка-то моя, ошибка, но я через openbsd её исправлю, поэтому мой ответ: "зачем это в 21 веке?" в силе...нравится топикстартеру строить песчаные замки, так ni.com в помощь, создаёшь схему, заказываешь плату и/или кристалл, ву-а-ля "ваше оборудование готово к работе"...
Сейчaс попытаюсь прояснить некоторые ключевые моменты моей аппаратно-портовой парадигмы… Раннее я уже где-то писал, что от ширины слова, записываемого в порт или читаемого, очень много зависит. Посмотрим вот сюда: out dx,eax - Передать адрес пакета. Здесь периферийный контроллер получает указатель на адрес в памяти приложения out dx,ax - Выбрать слой данных (reserved) out dx,al - Переключить статус пакета с указанием его направления. Если направление исходящее, по полученному раннее адресу считывается в сетевой буфер весь пакет из памяти приложения с проверкой целостности данных подсчётом CRC и открывается межсетевая передача до целевого пункта. Если направление запрашивающее, из целевого пункта запрашивается пакет, который затем будет записан в память приложения in eax,dx - Прочесть пакетное CRC in ax,dx - Прочесть статус слоя (reserved) in al,dx - Прочесть статус пакета Видно, что данные по одному и тому же порту не равнозначны (в зависимости от размера слова, порт принимает/отдаёт совершенно разный класс данных). В варианте с i386 всё проще, так как сама Операционная Система берёт на себя функцию периферийного контроллера и обрабатывает любой доступ к портам от приложения. При этом меняется принцип работы некоторых операций. rep outsd - Передать данные по адресу esi сервисному процессу с индексом edx. В ecx указывается объём данных rep outsw - Передача между слоями (reserved) rep outsb - Биндинговая передача (reserved) rep insd - Получить данные в буфер по edi от сервисного процесса с индексом edx в размере не более, чем указано в ecx rep insw - Приём из прослойки (reserved) rep insb - Биндинговый приём (reserved) Так, у процессоров x86 имеются инструкции «in al,imm8»…«out imm8,eax», где, аналогично как у i8080/z80, индекс порта задаётся непосредственной константой. В рамках идеологии системы этот регион портов я обозначил мусорными и назначил им свою особенную роль… Все эти нижние 256 портов в моей концепции операционной системы выполняют роль коммутаторов. Иными словами, если мы хотим, чтобы печатуемый на клавиатуре текст непосредственно выводился эхом на консоль, то необходимо построить граф и связать в нём клавиатуру с терминалом. Для этого нам нужен примерно такой код: Code (Text): ;;;;;;;;;;;;;;;;;;;;; Здесь мы поработаем с 32-битными данными как с указателями mov eax,Keyboard ; Задаём имя устройства ввода mov edx,12345 ; Выбираем произвольный порт out dx,eax ; Теперь этот порт - клавиатура mov eax,Display ; Задаём имя устройства вывода mov edx,54321 ; Выбираем любой понравившийся порт out dx,eax ; Теперь это порт алфавитно-цифрового дисплея mov eax,DataType ; Ссылка на описание типа данных out 123,eax ; Назначаем коммутаторному порту нашу "бирку" ;;;;;;;;;;;;;;;;;;;;; Теперь будем работать на "биндинговом уровне" с 16-битными словами mov ah,123 ; Указываем индекс коммутаторной ячейки mov al,0 ; Обнуляем, так как не используем mov edx,12345 ; Выбираем наш порт клавиатуры out dx,ax ; Назначаем выходным данным порт 123 xchg ah,al ; Меняем местами вход-выход mov edx,54321 ; Выбираем наш порт дисплея out dx,ax ; Назначаем входным данным порт 123 ;;;;;;;;;;;;;;;;;;;;; Мы построили здесь короткий граф и теперь ; драйвер клавиатуры будет отсылать код нажимаемых клавиш ; драйверу окна консоли, чем мы достигнем "эха" с клавиатуры на экран L1: in al,123 ; Читаем порт коммутации и следим за потоком cmp al,0x1B ; Если пользователь нажмёт клавишу Esc jne L1 ; Следует прервать цикл и разрушить наш граф связи xor eax,eax ; Обнуляем аккумулятор out 123,eax ; "Срываем бирку" с коммутаторного порта mov edx,12345 ; Теперь и наш порт клавиатуры out dx,eax ; Освобождаем mov edx,54321 ; И порт дисплея out dx,eax ; Удаляем из диспетчера консоли mov eax,1 ; Код завершения программы hlt ; Останавливаем нашу задачку Keyboard:db '/dev/console',0 ; Имя источника Display: db '/dev/tty1',0 ; Имя приёмника DataType:db 'ascii',0 ; Имя члена класса потока Таким образом, эти нижние 256 портов работают аналогично привычным нам COM-портам и наше приложение может связать любое одно системное устройство с другим. Так как ключевое слово 'ascii' знает и драйвер клавиатуры, и драйвер консоли, то в их канальной связи 'ascii' - общая шина обмена. Как здесь можно видеть, никаких call или int с вызовами системного API нам не потребовалось. Более того, и на уровне языка Бейсик, и на уровне языка Паскаль вся эта манипуляция с портами легко воспроизводима встроенными операторами inb/outd/outw. А значит, приложение не потребует загрузки каких-либо библиотек и выдаст одинаковый результат. Тем самым, можно свободно перенаправлять потоки и аудио, и видео, и назначать динамические компрессора и эквалайзеры, разделять и объединять каналы. При этом - никаких API. Всё на уровне распределения различных потоков по портам и их каналам.
Помните историю с Microsoft и Intel, где обсуждались основные проблемы системных вызовов? Если задуматься, то операции in/out моей концепции можно было бы обрабатывать достаточно быстро с использованием кеширования, если бы они были бы чисто виртуальными и работали аналогично как некие syspush/syspop со своим стеком событий и обращений к Системной Среде, как те же Win-API неблокирующее-отложенное PostMessage… Догадываетесь, о чём я говорю? Если бы с появлением i386 родилась бы и концепция Операционной Системе как полностью виртуальном компьютере, то с введением специального флажка в управляющем регистре процессора можно было бы выставить бит представления портов ввода-вывода как стека системных сообщений. И эти инструкции бы вообще не занимали бы много времени, а Система была бы полностью виртуализована как некий мощный аппаратный девайс. Большинство программ были бы максимально переносимыми между платформами. P.S.: Просто миру давным-давно требуется абсолютна новая концепция технологии архитектуры Операционной Системы…
сейчас это не так. начиная с 7 винды, ось умеет восстанавливаться. Но опять же если баг в драйвере видео, то тут и линукс упадет. Ничего не поможет.
Paguo_86PK, впихнуть апи в железку можно и нужно было сделать давно == сейчас в этом направление ползут, но главная проблема тут токЪ нарастает == тупо спецов не хватает, поэтому выгодней (даже для корпи) пилить унылую опенсорц софтвару. кстати, прикол ещё в том, что для производителей хардварные оси дают практически плюсы сплошняком... 1. зеро пиратство. 2. большой манёвр по техническим решениям == даже не самые оптимальные могут легко пахать в 10 раз быстрее софтинных аналогов. 3. появляются неплохие возможности по борьбе с вирусами == запас производительности позволяет делать более мажорные песочницы + си песочницы мб физически изолированы от доверенных юнитов жестянки (цпу, озу, пзу, гпу...). 4. можно добиваться также значительной экономии электричества. =========== Но-но-но.. --- Сообщение объединено, Nov 12, 2019 --- устойчивость линя в народе тоже излишне преувеличивается == он в куче случаев вроде и не падает, но так гнусно пахать начинает
UbIvItS, Гдe-то у меня были исходники эмулятора KolibriOS, в которых я пытался разобраться, но так и не смог. Сейчас ни у себя архив найти не могу, ни в сети, окромя битых ссылок. Проблема была в том, что вся среда KolibriOS под Windows воспроизводится лишь через «INT 0x40» под API и сегмент GS под экран. А порты ввода-вывода там вообще никак не задействованы в приложениях… Так как исходники - на ассемблере, да ещё с кучей Win-API, я даже пробовал переписать часть под Си, чтобы компактно изучить механизмы. Сами понимаете: Либо код Си на 25 строк, либо ассемблер на 25 страниц и грудой меток. Можно скостыльничать и вместо «in/out/ins/outs» подставить int-прерывания, как в DOS/Linux/KolibriOS. У пользователей даже придирок не будет, если так и представить всё, ведь выглядить будет всё демократично и стандартно! Spoiler in al,imm8 out imm8,al in ax,imm8 out imm8,ax in eax,imm8 out imm8,eax in al,dx out dx,al in ax,dx out dx,ax in eax,dx out dx,eax rep insb rep outsb rep insw rep outsw rep insd rep outsd rep cs: insb rep cs: outsb rep cs: insw rep cs: outsw rep cs: insd rep cs: outsd rep ds: insb rep ds: outsb rep ds: insw rep ds: outsw rep ds: insd rep ds: outsd rep es: insb rep es: outsb rep es: insw rep es: outsw rep es: insd rep es: outsd rep fs: insb rep fs: outsb rep fs: insw rep fs: outsw rep fs: insd rep fs: outsd rep gs: insb rep gs: outsb rep gs: insw rep gs: outsw rep gs: insd rep gs: outsd rep ss: insb rep ss: outsb rep ss: insw rep ss: outsw rep ss: insd rep ss: outsd lock in al,imm8 lock out imm8,al lock in ax,imm8 lock out imm8,ax lock in eax,imm8 lock out imm8,eax lock in al,dx lock out dx,al lock in ax,dx lock out dx,ax lock in eax,dx lock out dx,eax rep lock insb rep lock outsb rep lock insw rep lock outsw rep lock insd rep lock outsd rep lock cs: insb rep lock cs: outsb rep lock cs: insw rep lock cs: outsw rep lock cs: insd rep lock cs: outsd rep lock ds: insb rep lock ds: outsb rep lock ds: insw rep lock ds: outsw rep lock ds: insd rep lock ds: outsd rep lock es: insb rep lock es: outsb rep lock es: insw rep lock es: outsw rep lock es: insd rep lock es: outsd rep lock fs: insb rep lock fs: outsb rep lock fs: insw rep lock fs: outsw rep lock fs: insd rep lock fs: outsd rep lock gs: insb rep lock gs: outsb rep lock gs: insw rep lock gs: outsw rep lock gs: insd rep lock gs: outsd rep lock ss: insb rep lock ss: outsb rep lock ss: insw rep lock ss: outsw rep lock ss: insd rep lock ss: outsd (Здесь префиксы cs: ds: es: fs: gs: ss: не просто переключают сегменты, а указывают режим. Например, fs - File Stream, gs - Global Stream и т.д. Как и префикс LOCK, переключающий режим кооперации.) Итого - 108 INT-векторов! Против одного «INT 0x40» в KolibriOS или «INT 0x80» в Linux эти 108 - выходит как-то слишком громоздко и, главное, уродливо! Так как теряется вся суть и прелесть работы приложения с портами… Можно обойтись и одним INT'ом с последующей in/out инструкцией. Но это ещё большее уродство! Тут мне посоветовали ковырнуть https://github.com/Kelvinhack/kHypervisor, однако меня сильно смущает необходимость в VMware зачем-то! Нет, VMware у меня стоит. Но я не понимаю, для чего такая мощная прослойка, если KolibriOS-среда эмулировалась под Windows совсем независимо и компактно! Я же не полный кретин, чтобы пытаться писать свою систему начиная с загрузчика, а лишь идиот, которому нужно показать общие механизмы обработки исключений по «in/out/lock» и свернуть все 4 Гб пространства в зеркала из парочки Мб. Вот только не гуглится всё нормально! И ссылки битые. И исходники KolibriOS-эмулятора посеял. P.S.: Кажется, простая вещь из задачи программиста второго курса, а выполнить не могу…
UbIvItS, Спасибо! Однако, порты KolibriOS таки есть. Надо сейчас как-то в исходнике эмулятора отыскать этот момент, если он не выпилен только… И это строка 3174 файла I40EMUL.INC… Где стоит CreateFile??? А как же выдрать все 65536 портов под себя!? Windows же не позволит весь диапазон захватить!
Оказываeтся, меня понесло совсем не в ту степь! Во-первых, в Windows только верхние 32768 портов можно зарегистрировать. Во-вторых, всё намного упрощается при установке финального обработчика исключений. Например, код: Code (Text): #include "stdafx.h" DWORD nPorts = 0; LONG WINAPI TopLevelExceptionFilter(_EXCEPTION_POINTERS *ep) { DWORD ea = (DWORD)ep->ExceptionRecord->ExceptionAddress; BYTE *ic = (BYTE *)ea; if(0xEC == *ic) { DWORD port = ep->ContextRecord->Edx; printf("%08X %02X|IN AL,DX ; Port #%04X is bad; Ports available - %d\r", ea, *ic, port, nPorts); ep->ContextRecord->Eip ++; ep->ContextRecord->EFlags |= 1 << 11; // Overflow Flags ep->ExceptionRecord->ExceptionAddress = (void *)(ea + 1); return EXCEPTION_CONTINUE_EXECUTION; } return EXCEPTION_EXECUTE_HANDLER; } int main(int argc, char* argv[]) { SetUnhandledExceptionFilter(TopLevelExceptionFilter); printf("Hello World!\n"); for(int i = 0; i <= 0xFFFF; ++ i) { _asm { mov edx,i // Index of IO-Port in al,dx // Try for port-read jo err // Overflow if unaccessable inc nPorts err: } } printf("\nPorts available - %d\r\n", nPorts); return 0; } Выдаёт ожидаемый результат: Code (Text): Hello World! 00401157 EC|IN AL,DX ; Port #FFFF is bad; Ports available - 0 Ports available - 0 Press any key to continue Если Вы достаточно неплохо вникли в мою концептуальную идею в целом, то можете видеть, что всё работает как надо! Инструкция «in al,dx» генерирует исключение, мой обработчик отлавливает код 0xEC и корректирует EIP с установкой флага OF. А по «jo» прикладушка фиксирует переполнение из-за недоступности порта… Теперь нужно построить нормальный парсер под все комбинации «rep/lock/in/out/ins/outs/cli/sti» и можно уже эмулировать работу всех портов так, как я и задумал концептуально… По коду видно, что это - самое простое из начал. Сейчас нужно убедиться, что Windows действительно не даёт доступа ни к какому из портов. Затем то же самое нужно сделать с «int»-инструкциями… И самое сложное - искривление адресного пространства. Лет 5-10 тому назад я пытался перенастроить сегменты, но что-то не получилось. И ошибки не было, и адресного пространства задуманного не получилось. Немного теории Когда приложение настраивает, например, порт 0xFADEBA5E, в директории должен создастся файл «FADEBA5E.INI» или «FADABA5E.XML». То есть, формально - открывается файл. И даже если приложение мы закроем, не удаляя его портовых файлов, то при перезапуске приложения обнаружатся прошлые файлы и порты, тем самым, будут уже настроенными. То есть, приложение, фактически, под Windows можно «грохнуть» в любой момент, заархивировать и передать на другой компьютер с Linux, где всё распакуется и продолжит работать с точки «гроханья». Главное, чтобы никакие INI/XML-файлы не изменились вручную. Да, и файл «cpu.ini» должен хранить весь регистровый файл, и файл «ram.ini» настройку всех зеркал памяти… Немного механики Та же самая KiCAD состоит из отдельных утилит, которые обмениваются файлами между собой: Рисуешь схему в редакторе и запускаешь редактор топологии печатной платы, в котором запускаешь 3D-вьювер своего изделия. Концептуально у меня - почти так же: Открываешь приложением порт и настраиваешь его. Создаётся под порт файл, который потом может быть передан как в Chrome, если это svg-разметка, так и в VLC, если это потоковое видео. Да, для HTML-сценариев должны быть ещё интерактивные порты под сокеты. То есть, в принципе, в этом и заключается вся суть задумки: Не приложение должно рисовать 3D-сцену средствами API-вызовов, а должно терпеливо ждать готовности порта ввода-вывода, пока системное окружение само не построит сцену в браузере и вернёт результат. То есть, in/out-инструкция может задержать само приложение на миллиарды тактов или десятки минут. P.S.: В общем, не знаю, одолею ли я всё это…
Тaк то оно и есть. Хотя, в VMware этих ограничений нет, так как там иные механизмы, чем банальный гипервизинг. Но, я понял другой момент… Регистрация портов в Windows по-хорошему нужна лишь для нормальной работы с ними из-под остальных приложений посредством Win-API с CreateFile и т.д… А так как у меня доступ к API прямыми вызовами не предусматривается в принципе, то и регистрация портов, как объектов ядра и части файловой системы мне, оказывается, не нужна. Достаточно тупо отлавливать ошибки, парсить байт-код инструкций и отрабатывать его интерпретацию. Ночью переписал свой код более-менее нормально. Парсинг инструкций теперь происходит более полнее с накопление всех префиксов. В частности, устанавливаются флаги сигнализации участвующих регистров. Как отображает поверхностный тест, порядка 18 млн тиков уходит на обработку четырёх исключений. Да, это очень много. Но, этими тактами не единственный пиксель читать нужно, а производить комплексную работу с файлами и сетевыми транзакциями, что должно компенсировать общую просадку производительности. Code (Text): 00401ED2 00000CEC |REPE LOCK (ECX) IN AL,EDX EAX:AF9BF4CA ECX:84299604 EDX:00003EB3 00401ED5 00000CFF |REPNE LOCK (ECX) OUT EDX,EAX EAX:AE48DA3F ECX:84299604 EDX:00003EB2 00401ED8 00000CEA |REPE LOCK (ECX) CLI ECX:84299604 00401ED9 0000000B |STI maximum: current: 00401EDE 00000009 |HLT 16917096 > 13039800 ticks Черновой вариант кода (Должно, конечно, быть несколько иначе, так как этот код не открывает никаких файлов.) P.S.: Сейчас попробую доковыряться с управлением памятью.
тоже обрубок == когда дело касается использования видюхи, сразу ощущаешь куцость вм-ки просадку в ринге3 едва ль удастся убрать == можно сделать дравер и работать с портами напрямую чрез него, но скорей всего получишь много удовольствия с падучей всей оси. можешь попытаться связаться с этим челом http://wiki.kolibrios.org/wiki/User:XVilka можь он тебе эки-нть идеи решения подкинет.