Слышали о таком? Я пробовал - работает Код (Text): code segment use32 xor eax, eax mov ds, eax mov dword ptr ds:[0B8000h], 'S' ;Вывести на экран 'S' cli mov word ptr ds:[8*4], small offset irq0_handler mov eax, cs mov word ptr ds:[8*4+2], ax sti ... irq0_handler: push eax mov al, 20h out 20h, al pop eax iretd code ends Как его сделать: Переходим в защищённый режим, загружаем в cs 32-битный дескриптор, во всех сегментах устанавливаем лимит 4 Гб, и возвращаемся отратно в реальный режим. 32-битный режим работает и в реальном режиме, прерывания работают, вся память доступна
Фича, уже хрен знает сколько лет известная как unreal mode. Хотя в интеловских мануалах о ней по прежнему ни слова. ЗЫ. mov ds, eax - у тебя это компилируется?
Конечно, это компилируется нормально Разница в разрядности процу по боку. Более того mov ds,ax в 32-битном режиме длиннее на префикс. По поводу сабжа - автор гонит. Ибо то что у него работают 32-битнае команды не значит что он в 32-битном режиме. И дескриптор (наверное селектор ) он загрузил не 32-битный, а просто с большим (4Гб) лимитом. Ибо в истинном 32-битном реальном режиме нет смысла нифига - тот же протектед, т.к. БИОС работать не будет. БИОС 16-битный. Представь там написано mov ax,1234h; mov dx,5432h. Представил? А теперь мы в 32-битном режиме. Опкоды mov ax,1234h интерепретируются как mov eax,xxxx1234h где хххх - кусок следующей команды. Как ты думаешь, всё будет нормально работать?? Твой же код работает - никто не спорит, только это то же самое что вместо use32 поставить use16 и все мнемоники регистров заменить на аналогичные 16-битные. Впиши в начало проги указанные выше команды и убедишься что ничё работать не будет. А просто Unreal - согласен, прикольная штука Я пока с РМ не разобрался активно пользовал.
в принципе, 32-битный unreal теоретически должен работать не хуже обычного unreal, но вот вопрос зачем он такой нужен. Вся прелесть unreal ведь и была в том, что можно работать как в RM, вызывать DOS, BIOS и тп и в то же время линейно адресовать все 4Гб. Формат shadow-регистров сегментных дескрипторов таков (процы Intel, для P4 и старше, включая те, что с поддержкой EM64T: DWORD База сегмента, собранная в цельный 32-битный адрес из дескриптора DWORD Биты доступа (см. ниже) DWORD Предел сегмента, переведенный в байты (с учетом G) Биты доступа: бит 16 = G, 15 = D (то самое теоретическое обоснование возможности unreal 32), и тд, включая ошметки предела сегмента из дескриптора, биты 8-1 = AR, бит0 = 0 (т.е. сдвинуты на 1 влево). Весьма забавно, что у процев с EM64T формат shadow-регистров не изменился, возможно из-за игнорирования базы и предела в long mode.
Дык и я про то. Я не говорю что 32-битный unreal невозможен в принципе. Просто автор уверяет что у него в 32-бит Unreal BIOS работает. А я заявляю что это невозможно, кто не согласен покажите рабочий код. А нет BIOS, дык тогда уже лучше в полноценный РМ переходить.
Я не говорил, что BIOS работает. Прерывания работают. А драйвера пишем сами, ручками. В чем прелесть - это 32битный код. А в 16-битном сегменте перед каждой командой будет стоять префикс 66h. Интересен сам 32битный реальный режим - он нигде не описан. Причем адрес обработчика прерывания - 16-битный. Процессор сам дополняет верхнюю часть cs и eip нулями. Работает и такое Код (Text): code segment use32 mov eax, offset some_label mov ebx, cs lea eax, [eax+ebx*4] ;eax=eip+cs*4 push 0 ;новый cs push eax ;новый eip retf some_label: ... code ends В PM вы так сделать сможете?
droopy В доках сказано что код, который сбрасывает бит PE должен находиться в сегменте с лимитом 64К. В этом 32х-битном реальном режиме в EIP можно записать число более 0FFFFh или нет?
eip > 0FFFFh можно было и в обычном unreal иметь, только для этого надо было префикс размера операнда перед каждым near jump'ом выше 1 Мб указывать. Интел хорошо сделали, что отменили (начиная с pentium'а) сброс access rights в shadow дескриптора CS на дефолтовые реалмодовые значения при смене регистра CS (FAR CALL/JMP, etc.) в реал моде. Поддержали undoc так сказать. add: Попробовал такой код -- пищит, т.е. обе проверки прошли: 1) 32-битный размер операнда/адреса и 2) переживание перезагрузки CS. Код (Text): ; -> to unreal32 ; CS ShadowDescriptor.D = 1 (Code32) mov eax, cr0 and al, 0FEh ; PE = 0 mov cr0, eax ; db 0EAh dw offset in_real_mode dw 0 ; !!! RM_CS_seg dw ? in_real_mode: db 0B8h dw 1234h db 33h, 0C0h cmp al, 0 jz _16_bit in al, 61h or al, 3 out 61h, al _16_bit:
Кстати сказать, для остальных сегментных регистров то же самое. А что, на 386,486 теневые регистры сбрасывались в дефолт при изменении сегментных регистров? Сам проверить не могу - не на чем
про это Р.Коллинз писал еще хз когда In fact, only the CS descriptor caches for the 286, 386, and 486 get loaded with fixed values each time the segment register is loaded. Loading CS, or any other segment register in real mode, on later Intel processors doesn’t change the access rights or the segment size limit attributes stored in the descriptor cache registers. For these segments, the access rights and segment size limit attributes from any previous setting are honored.
Тогда сори, не так понял. С этим согласен Согласен, но прелести не вижу. Вся прелесть Unreal в доступности BIOS и DOS. А если их нет - тогда 32-бит РМ и все дела. Пожалуй только eip, т.к. cs по любому 16-битный (не считая теневой части). Нет, не смогу - а надо ли? Это в доках сказано как в обычный реал перейти. А если не делать как в доках написано - как раз тогда интересные фокусы получаются. Как написал _BC_ можно и в обычном 16-бит Unreal - главное лимит поставить больше 64К, обычно 4Гб юзают.
Правильно Medstrax заметил, там на 16 умножать надо было. Примерно так: shl ebx, 4 add eax, ebx Просто я давно уже асмом не занимался, только из армии пришел. В 32-битном режиме проц считает сегментные регистры 32-битными. Команда mov ax, cs идет с префиксом 66h, а push cs отнимает у esp 4 байта. Только он пишет/читает младшие 16 бит.
Никто ж не спорит. Но это не меняет факта что сегментные регистры 16-битные. Просто так удобней (считать их 32-битными) - лучше для выравнивания и т.д. Всё равно при записи во внешние приёмники старшие 16 бит обнуляются.
Здесь префикс указывает на то, что будет использоваться регистр ax, а не eax. Никакого отношения к разрядности cs он не имеет. На старых пеньках старшие 16 бит остаются неизменными. Если речь идет о РОН. При записи в память - хз
mov r/m, seg (8Eh) обнуляет старшие 16 бит dest если в 32-битном режиме (или в 16-битном с префиксом 66h) и если dest -- регистр. Если dest -- память, то сохраняется всегда word, пох на режим/префикс.
Ну вот и прояснили Лениво было в манах копаться - я предпочитаю не забиваться на то, что там в старших 16 битах при работе с seg_reg, вот и всё. А для общего развития полезная информация. Спасибо за детальное разъяснение.