Вы не застали времена ZX-Spectrum, Микроши и Atari-XE? Ну, тогда к слову, тоже к слову: Код (Text): long GetLastError(void) { long error_code; _asm mov eax,gs:[API_STATUS]; _asm mov [error_code],eax; return error_code; } Чем выделять в Win-API функцию GetLastError, могли бы просто выделить область служебных ячеек. Модификация которых не приведёт к краху, так-как все они - условные, для локального использования или псевдо-локального.
Кстати про это выгуглить я не смог. Где описаны все gs:[xxxx] векторы? Встречал лишь в установщиках try..catch и больше нигде... :\
Регистр Gs при свапконтексте обнуляется. Использование его для адресации приведёт к #GP. TEB адресует селектор в регистре Fs по дефолту. Вобще я говорил про системные переменные в этом блоке. Это параметры стека и есчо некоторые используемые ядром. Остальные поля не системные, а пользовательские. pebteb.h Код (Text): typedef struct PEBTEB_STRUCT(_TEB) { PEBTEB_STRUCT(NT_TIB) NtTib; PEBTEB_POINTER(PVOID) EnvironmentPointer; PEBTEB_STRUCT(CLIENT_ID) ClientId; PEBTEB_POINTER(PVOID) ActiveRpcHandle; PEBTEB_POINTER(PVOID) ThreadLocalStoragePointer; PEBTEB_POINTER(PPEB) ProcessEnvironmentBlock; ULONG LastErrorValue; ULONG CountOfOwnedCriticalSections; PEBTEB_POINTER(PVOID) CsrClientThread; PEBTEB_POINTER(PVOID) Win32ThreadInfo; // PtiCurrent ULONG User32Reserved[26]; // user32.dll items ULONG UserReserved[5]; // Winsrv SwitchStack PEBTEB_POINTER(PVOID) WOW32Reserved; // used by WOW LCID CurrentLocale; ULONG FpSoftwareStatusRegister; // offset known by outsiders! PEBTEB_POINTER(PVOID) SystemReserved1[54]; // Used by FP emulator NTSTATUS ExceptionCode; // for RaiseUserException // 4 bytes of padding here on native 64bit TEB and TEB64 PEBTEB_POINTER(PACTIVATION_CONTEXT_STACK) ActivationContextStackPointer; // Fusion activation stack #if (defined(PEBTEB_BITS) && (PEBTEB_BITS == 64)) || (!defined(PEBTEB_BITS) && defined(_WIN64)) UCHAR SpareBytes1[28]; // native 64bit TEB and TEB64 #else UCHAR SpareBytes1[40]; // native 32bit TEB and TEB32 #endif PEBTEB_STRUCT(GDI_TEB_BATCH) GdiTebBatch; // Gdi batching PEBTEB_STRUCT(CLIENT_ID) RealClientId; PEBTEB_POINTER(HANDLE) GdiCachedProcessHandle; ULONG GdiClientPID; ULONG GdiClientTID; PEBTEB_POINTER(PVOID) GdiThreadLocalInfo; PEBTEB_POINTER(ULONG_PTR) Win32ClientInfo[WIN32_CLIENT_INFO_LENGTH]; // User32 Client Info PEBTEB_POINTER(PVOID) glDispatchTable[233]; // OpenGL PEBTEB_POINTER(ULONG_PTR) glReserved1[29]; // OpenGL PEBTEB_POINTER(PVOID) glReserved2; // OpenGL PEBTEB_POINTER(PVOID) glSectionInfo; // OpenGL PEBTEB_POINTER(PVOID) glSection; // OpenGL PEBTEB_POINTER(PVOID) glTable; // OpenGL PEBTEB_POINTER(PVOID) glCurrentRC; // OpenGL PEBTEB_POINTER(PVOID) glContext; // OpenGL ULONG LastStatusValue; PEBTEB_STRUCT(UNICODE_STRING) StaticUnicodeString; WCHAR StaticUnicodeBuffer[STATIC_UNICODE_BUFFER_LENGTH]; PEBTEB_POINTER(PVOID) DeallocationStack; PEBTEB_POINTER(PVOID) TlsSlots[TLS_MINIMUM_AVAILABLE]; PEBTEB_STRUCT(LIST_ENTRY) TlsLinks; PEBTEB_POINTER(PVOID) Vdm; PEBTEB_POINTER(PVOID) ReservedForNtRpc; PEBTEB_POINTER(PVOID) DbgSsReserved[2]; ULONG HardErrorMode; PEBTEB_POINTER(PVOID) Instrumentation[14]; PEBTEB_POINTER(PVOID) SubProcessTag; PEBTEB_POINTER(PVOID) EtwTraceData; PEBTEB_POINTER(PVOID) WinSockData; // WinSock ULONG GdiBatchCount; BOOLEAN InDbgPrint; BOOLEAN FreeStackOnTermination; BOOLEAN HasFiberData; BOOLEAN IdealProcessor; ULONG GuaranteedStackBytes; PEBTEB_POINTER(PVOID) ReservedForPerf; PEBTEB_POINTER(PVOID) ReservedForOle; ULONG WaitingOnLoaderLock; PEBTEB_POINTER(ULONG_PTR) SparePointer1; PEBTEB_POINTER(ULONG_PTR) SoftPatchPtr1; PEBTEB_POINTER(ULONG_PTR) SoftPatchPtr2; PEBTEB_POINTER(PPVOID) TlsExpansionSlots; #if (defined(_WIN64) && !defined(PEBTEB_BITS)) \ || ((defined(_WIN64) || defined(_X86_)) && defined(PEBTEB_BITS) && PEBTEB_BITS == 64) // // These are in native Win64 TEB, Win64 TEB64, and x86 TEB64. // PEBTEB_POINTER(PVOID) DeallocationBStore; PEBTEB_POINTER(PVOID) BStoreLimit; #endif LCID ImpersonationLocale; // Current locale of impersonated user ULONG IsImpersonating; // Thread impersonation status PEBTEB_POINTER(PVOID) NlsCache; // NLS thread cache PEBTEB_POINTER(PVOID) pShimData; // Per thread data used in the shim ULONG HeapVirtualAffinity; PEBTEB_POINTER(HANDLE) CurrentTransactionHandle;// reserved for TxF transaction context PEBTEB_POINTER(PTEB_ACTIVE_FRAME) ActiveFrame; PEBTEB_POINTER(PVOID) FlsData; BOOLEAN SafeThunkCall; BOOLEAN BooleanSpare [3]; } PEBTEB_STRUCT(TEB), *PEBTEB_STRUCT(PTEB);
Однако, опять-таки меня не поняли. Давайте я поступлю тупо. Допустим прошло уже 5-10 лет и видеокарты полноценно сами распределяют свой контекст между приложениями. В 64-битных приложениях, где адресное пространство ого-го(!!!) и тупые функции SetPixel/GetPixel/DrawText вообще можно заменить на прямое обращение к железу: Код (Text): long GetPixel(HDC hdc, long x, long y) { _asm mov edi,fs:[VIDEO_DRIVE]; // Читаем адрес видео девайса _asm mov edi,[edi][CONTEXT_2D]; // ищем порт контекста _asm mov eax,hdc; _asm mov [edi][FLAT_HDC],eax; // устанавливаем контекст L1: _asm cmp [edi][FLAT_HDC],eax; // ждём, пока видяха будет готова переключить _asm jne L1; _asm mov eax,[edi][SURFACE_WIDTH];// читаем ширину контекста _asm mul [y]; _asm add eax,[x]; _asm mov edi,[edi][SURFACE_RGBA]; // узнаём непосредственный адрес Bitmap _asm mov edi,[edi][eax*4]; // читаем пиксел } Нафиг системе выделять кучу дурацких функций, если видяха сама всё может выполнить? Ведь сами подумайте. Покупаем новейщий GeForce, стираем нафиг всю его умную прошивку со всеми шейдерами и вшиваем свою, простую и тупую. Пишем тупой драйвер и без всяких заморочек все значки на XP-столе - не статические тупые ICO, а ANI-анимашки с нулевой нагрузкой на пень! Скажите не слабо ребятам nVidia сделать такие тупые свистелки? А не. Здесь не технические ограничения, а долбанная философия. Что должно делать железо, а что - софт. От того и пни пухнут от всевожможных эффектов, некоторые из которых были ещё в Atari 80-ых. Знаете что? ) Я гляжу все зациклились на кислом бульоне от IBM и MS. А так если глянуть и выбросить лозунг "абстракция от железа", то вы забудете слово "привязка к железу", так-как железо станет не портами ввода-вывода, а сопроцессором со своими командами прямо в системе команд ЦП. Помнится и FPU-команды эмулировались в дёщевых XT-AT до i486. А что мешает, скажем, тупо выбросить FPU и сделать там SVGA-команды в PC-XT!? Получим слабый комп, но с сильным графическим сопроцессором... В идеале, по идее, де-факто, что используется десятилетиями, должно поглощаться процессором. Мышь-клавиатура-видяха - всё на правах со-процессоров и имеют команды, типо: Код (Text): VINIT - Инициация контекста видео устройства VWAIT - Ожидание готовности контекста TINIT - Инициация терминала (клавиатура-мышь-спикер) TIN EAX,SCAN_CODE - Ввод скэн-кода клавиши (это не IN EAX,0x64, а совсем иное) Вы сами в курсе, что в x86 дофига зарезервированных команд, которые Intel запрещает использовать. (гляньте в мусорку FE/FF - помимо CALL/JMP/POP/INC и прочего, там ещё целых 64 кодов пустуют!) Глядишь, вымрет вся линейка x86, а весь потенциал кодов - гиене под зад ( Это же искусственные ограничения, а вы поддались! FPU тоже аппаратный и порты имеет, но они чётко прописаны...
Paguo_86PK Затрудняюсь какой вам диагноз поставить Это всё красиво было, но давно вымерло. Мощные системы требуют сложных решений.
Paguo_86PK > Скажите не слабо ребятам nVidia сделать такие тупые свистелки? А не. > Здесь не технические ограничения, а долбанная философия. философия не религия. если что-то не сделано, то: 1) это никому на хрен не нужно (или не стоит усилий); 2) это всем нужно, но хрен знает как его сделать дешево и удобно; 3) это всем нужно и технически не сильно сложно, но это ломает остальные решения и быстрый переход невозможен; например, я удивился когда увидел что информационное табло в порту это целый комьютер даже еще и под вынь, причем под каждое табло он по ходу дела свой. охренеть какой оверхид! но если подумать... специализированное решение в силу своей малотиражности обойдется дороже. будет польше проблем с поддержкой. и главное - в общем зачете это копейки. на мелочах не экономят. а от железа действительно лучше абстрагироваться. сейчас еще ничего. а вот лет 15 назад когда на рынке была куча звуковых карт, то это был кошмар разработчиков даже с учетом того, что многие карты были совместимы с блястером. а гуся вспомните? що блин за насилие такое: нет гуся - нет звука. что же по поводу гибели линейки интел... все течет, все меняется. безотносительно качества.
Вы не были на вокзале Алматы. Там висят LCD-телевизоры и транслируют ролики специфические про взвес багажа и т.д. А когда пригляделся - офигел! Изображение зашумлено и двоится. Я так понял, они тупо повесили те телевизоры и подвели к ним питание, а на НЧ-кабеле съэкономили. Обошлись одним общим RF-транслятором... Ещё над каждой дверью установленны часы, показывающие время, температуру, рекламу бегущей строкой. Так температура и время везде были различными. Тупо поставили без центральной синхронизации. И гадаешь, какие идут правильно!!! XXI век. Ну я уже понял: Де@#ма и отстоя ещё хватит лет так на 50 ещё... :-\
Paguo_86PK Опять вас не понять. nvidia не делает свистелок и перделок? Делает, но только те от которых есть прибыль, вот она философия. К примеру этих свистелок напихали в кеды, но толку от них. Эти эффекты чисто на посмотреть и выкинуть. Что это значит? Работаем напрямую с железом, здравствуй дос? Вообще-то есть современные, эффективные, высокоуровневые интерфейсы. Куда-то вас всё в прошлое несёт.
Paguo_86PK > Вы не были на вокзале Алматы. Там висят LCD-телевизоры и транслируют ролики не был. но вот даже в краснодаре как-то погас свет, а потом снова зажегся и на всех экранах вспыхнул биос и пошли грузится винды причем везде с разной скоростью. из чего я сделал вывод: по одному компу на экран. а в домодедово эти компы и так глазами видно за мониторами на стойках.
Вы решительно внушили, что я несу ересь и не слышите ни слова... Я говорю о том: 1) Система, перед передачей кванта машинного времени очередному приложению, уведомляет железо о том, что нужно переключиться на контекст данной задачи: Видеопамять графическая или консоль, аудиокарта и т.д. Ведь что мешает текстовое окно консоли (консоль - не а-ля ДОС, а *никс-подобное приложение, апачи например) отрисовывать не менеджером, а процессором видяхи? Ведь в нормальном состоянии видяха тупо нагружена на 1-2%! Что зря мощи пропадать? 2) Приложение, получив квант времени, для обращения к OpenGL и звуку не требует вызова заумных функций. Прямо в видеопамять посылается GL-скрипт байт-кодом и строится сцена на высоком уровне. Причём здесь ДОС-времена, когда программировались тупые порты и линии строились пикселами? Всё новое - хорошо забытое старое! Что мешает порт 96 использовать как порт клавиатуры(традиционно), но клавиатура - может быть потоком из сети или файла. Ведь нету или очень редки утилиты, которые содержимое файла транслируют под видом порта клавиатуры или т.п.
Paguo_86PK Фантастика. Ничего, что железо по определению не многозадачно? По вашему рисует не процессор видяхи, а менеджер? Однако. Вы хотите часть работы операционной системы преложить на железо? Лол. Это конечно прикольно, но чем мешают функции? Чтобы послать, всё равно нужно что-то вызвать. Тем, что вы предлагаете выкинуть абстрактную прослойку, вернув нас во времена зависимости от аппаратной реализации.
Опять-таки непоняточки. Вспомните Windows'98 и то, что раньше EGA/VGA-адаптеры были с портами Read-Only. А операционки должны же были как-то сохранять контекст (или turbo debug). И разработчики пошли по простому, но дурацкому пути: теперь регистры и пишутся, и читаются... Нет чтобы сделать вдобавок страничность у регистров. Хоп, и контекст одной командой переключился в режим нужной задачи. Не надо читать-восстанавливать сотню-другую регистров. А в даташит по видяхе указывается: Поддерживает до 16 контекстов. Т.е. в винде это гарантировало 100% отсутствие глюков при переключении от Doom-подобных игр к столу винды. Или вы забыли, как в Mortal Kombat палитра на глазах восстанавливалась? Что мешало каждый важный регистр заменить на память в 16-64 ячейки? Удорожание на $1-$5??? Помилуйте, не пожалел бы я этих денег. Оно того стоило. И в нервах, и в глюках. Один вызов - сколько тактов? Или вы не копались в векторе Int 0x21? Куча cmp al,...je... веток, скорость то не световая! И зачем вызывать SetPixel, если видяха сама знает позицию окна и можно смело писать в графический фрейм, так-как система заранее подгрузила страницу регистров контекста и видяха знает, что такой-то пиксел фрейма имеет такую-то позицию на десктопе окна. Какрас-таки абстракция обеспечивается процессором видяхи. Не надо после каждого изменения битмапа делать BitBlt в окно: Видяха сама диспетчер такой-то области и опционально может шпионить за битовыми картами и оперативно выводить их на экран... На эту тему я уже писал: Вместо RGB-пикселей на десктопе выводятся только индексы. Т.е. система окна рисует не цветом, а Overlay-прямоугольником до 65536 комбинаций. Каждому приложение выделяется свой Overlay. Надо передвинуть окно - система двигает лишь монотонный прямоугольник, а видяха в реальном режиме времени в него рисует содержимое любой области памяти, хоть с физического 0x00000000... Или, по принципу контекста, область 0xA00000000 - видяха. Но переключая контекст регистров, одно приложение записывая туда, перенапрявляется шиной на нужное смещение, соответствующее позиции окна в общем десктопе. А другое приложение - в другое. Система лишь вписывает перед переключением на задачу один лишь номер контекста в один порт видяхи. А приложение не работает с видяхой и портами, а оперирует на уровне DDraw и BitSection... Я в off на 21 час. А то все возмущались, что я молчу. Тариф платный пошёл уже
Обижаете. Про кольца я в курсе и что сделать то, о чём говорю - раз плюнуть. Только как!? Вот допустим у меня Windows'2K стоит на P-90 (48mb-RAM, 40gb-HDD) в качестве сервера (я ща тут через его модем сижу, а браузер - на P-4). Так вот, искал я под тот пень эмул MMX-инструкций. Под линукс нашёл быстро + сорсы. А под винду - автор признался, не знает, как сделать... Обидно... Есть у меня один проект, который тоже оплевали на форуме... Суть такова: Virtual Dub фильтр написать - очень просто. Что я и сделал. Но тут же подумал о универсальном фильтре, гибком со скриптами. Но быстрым! Возиться с Lua/Java? Не оправдается... И тогда я придумал такой скрипт: Основа: Все x86-инструкции используем как байт-код скрипта, но их функционирование несколько меняется. Так, например MOV EAX,[0x12345678][ESI][EDI*4] интерпретируется как EAX = GLOBAL_STRUCTURE[0x123].SUB_STRUCTURE[0x45].ELEMENT[0x678+ESI][EDI*4]... Написал дизассемблер на подобном уровне, чтобы легче было скрипт писать. Транслятор делает что? Скажем, нужно скриптом написать hdc = GetDC(hWnd); SetPixel(hdc, 128, 127, 0xFFEECC); В скрипте это описывается как Код (Text): 0xFDC..... -> Functions using DC: 0x...9D... -> 9et Dc -> GetDC; 0x...5D... -> relea5e Dc -> ReleaseDC; 0x...EC... -> sEt Color -> SetPixel; 0x...9C... -> 9et Color -> GetPixel; 0x...D1... -> Draw 1ine -> LineTo; 0x...E0... -> movE t0 -> MoveTo; 0x...E5... -> Ellip5e -> Ellipse; 0x...DE... -> Draw tExt -> DrawText; etc... 0xAAA..... -> All Arrays vAriables: 0x...1D... -> w1nDow -> hWnd; 0x...1A... -> 1pAram -> lParam; 0x...59... -> m59 -> msg; 0x...15... -> 1n5tance -> Instance; etc... 0x000..... -> local variables frame 0x...xxxxx -> variable[0..1048575] MOV EAX,[0xAAA1D000] интерпретируется в MOV EAX,[hWnd] MOV FS,[0xFDC9D000] интерпретируется в MOV [tmpFS],GetDC MOV EAX,FS:[EAX] интерпретируется в PUSH EAX и CALL [tmpFS] и LEA ESP,[ESP][4] MOV CS,[128] интерпретируется в XCHG EAX,[tmpCS] и LEA EAX,[128] и XCHG [tmpCS],EAX MOV DS,[127] интерпретируется в XCHG EAX,[tmpDS] и LEA EAX,[127] и XCHG [tmpDS],EAX MOV FS,[0xFDCEC000] интерпретируется в MOV [tmpFS],SetPixel ... тем самым получаем: _код_ _скрипт_ _x86-мнемоника_ _итоговый_объектный_код_ 8B 05 00 D0 A1 AA|MOV EAX,Variables.hWnd |MOV EAX,[0xAAA1D000] |MOV EAX,[hWnd] 8E 25 00 D0 C9 FD|MOV FS,Functions.GetDC |MOV FS,[0xFDC9D000] |PUSH offset GetDC |POP [tmpFS] 64 8B 00 |MOV EAX,FS(EAX) |MOV EAX,FS:[EAX] |INVOKE [tmpFS],EAX 8E E8 |MOV GS,AX |MOV GS,AX |MOV [tmpGS],EAX 8E 25 00 C0 CE FD|MOV FS,Functions.SetPixel|MOV FS,[0xFDCEC000] |PUSH offset SetPixel |POP [tmpFS] B9 80 00 00 00 |MOV ECX,128 |MOV ECX,128 BA 7F 00 00 00 |MOV EDX,127 |MOV EDX,127 B8 CC EE FF 00 |MOV EAX,0x00FFEECC |MOV EAX,0xFFEECC 64 65 89 04 11 |MOV FS(GS,ECX,EDX),EAX |MOV FS:GS:[ECX][EDX],EAX|INVOKE [tmpFS],GS,ECX,EDX,EAX И используя Hiew или другие инструменты, легко и быстро набросать скрипт байт-кодом. Инкапсуляция достигается легко без всяких сложных приёмов... Однако всем идея использования x86-кода в качестве базового байт-кода скрипта сразу не нравится прямо в штыки!
Paguo_86PK Вам прямая дорога к технологиям продвигаемых amd, которые объединяют cpu и gpu. На данном этапе это раздельные вещи. Перенести в видеокарту код отрисовки окон это конечно интересно, только я не понимаю что это даст. Основной код, который влияет на поведение окон всё равно в cpu. Или вcё перенести в gpu?
Ну конечно, если у вас мамка на два проца по 8 ядер каждый, тогда десяток полупрозрачных окошек на столе будут просто летать. В ином случае, увы, смотришь и думаешь "а нафига я копил на эту видяху, если под тупые игры у неё заточка?"...