пишу прогу для msdos 6.22, необходимо много памяти и быстрый доступ до нее. идеально подходит нереальный режим (32-битная адресация и 16-битный код обращения к функциям биоса, доса и обработки прерываний) + конечный автомат (как инструмент управления бесконечным-зацикленным массивом). нашел рабочий код только используется из паскаля, проверял - работает. весь мой код написан на плюсах и жестко 16-разрядный, проблема интеграции ассемблерного кода в основной код.... использую Borland C 3.1 дошел до кода перехода в защищенный режим и загрузки сегментных регистров дескрипторами 4-гигабайтных сегментов (PMode), вываливается на операции Код (Text): mov cr0, eax . Ассемблерный код: Код (Text): .386p public _PMode code segment para public use16 assume cs:code ;УКАЗАНИЕ "SYSCALL" ВМЕСТО "pascal" НЕ ПОМОГЛО _PMode proc pascal near ; определить линейный адрес GDT xor eax, eax mov ax, cs shl eax, 4 lea edx, GDT add eax, edx ; заполнить GDTR физическими адресами GDT mov dword ptr CS:GDTR+2, eax push ds ; запомнить сегмент кода ; перейти в защищенный режим cli ; запретить прерывания lgdt fword ptr cs:GDTR ; загрузить GDT mov eax, 1 ; mov CR0, eax ; защищенный режим разрешен ; загрузить все сегментные регистры дескриптором с лимитом 4 Гб mov ax, 8 ; 8 - селектор нашего дескриптора mov ds, ax mov es, ax mov fs, ax mov gs, ax ; снять ограничения с сегмента gs xor eax, eax ; mov CR0, eax ; перейти в реальный режим sti ; разрешить другие прерывания pop ds ret GDT dq 0, 8F92000000FFFFh; глобальная дескрипторная таблица: GDTR dw 16, 0, 0 ; регистр таблицы глобальных дескрипторов: _PMode endp code ends end Код в cpp: Код (Text): #include .... #pragma inline extern "C" void PMode (void); void Enable_A20 (void) { asm push ax asm in al, 92h asm or al, 02h asm out 92h, al asm pop ax } void Disable_A20 (void) { asm push ax asm in al, 92h asm and al, 02h asm out 92h, al asm pop ax } unsigned char Check_Safety (void) { unsigned short XXX; asm smsw XXX // прочитать слово состояния процессора //(копирует младшие 16 бит регистра CR0 в ХХХ) asm mov ax, XXX if (XXX==1) // проверяем состояние: return 1; // если 1 - процессор в защищеном режиме asm mov ax, 4300h // проверить наличие XMS asm int 2Fh // прерывание мультиплексора // (запрос на доступ к НМА) // если Himem.sys загружен то 64K в НМА // заняты и регистр ax принимает значение // ax = 4A02h (выделить часть НМА) asm shr ax, 6 // сдвиг вправо на 6 бит asm and ax, 2 // проверить наличие Himem.sys // если 2 - Himem.sys установлен // если 0 - все OK XXX = 0; asm mov XXX, ax return XXX; } int main () { ..... s = Check_Safety (); if ( s != 0 ) exit (0); Enable_A20 ();//работает PMode (); ..... Disable_A20();//работает ..... }
обычно делают Код (Text): mov eax, cr0 or eax, 1 mov cr0, eax и Код (Text): mov eax, cr0 and eax, 0xFFFFFFFE mov cr0, eax в GDTR лимит должен быть на 1 меньше, т. е 15 попробуй посмотреть весь сгенерированный код в целом