UNREAL MODE (ASM + C)

Тема в разделе "WASM.ASSEMBLER", создана пользователем lvccgd, 1 июл 2007.

  1. lvccgd

    lvccgd New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    8
    пишу прогу для msdos 6.22, необходимо много памяти и быстрый доступ до нее. идеально подходит нереальный режим (32-битная адресация и 16-битный код обращения к функциям биоса, доса и обработки прерываний) + конечный автомат (как инструмент управления бесконечным-зацикленным массивом).
    нашел рабочий код только используется из паскаля, проверял - работает.
    весь мой код написан на плюсах и жестко 16-разрядный, проблема интеграции ассемблерного кода в основной код....
    использую Borland C 3.1

    дошел до кода перехода в защищенный режим и загрузки сегментных регистров дескрипторами 4-гигабайтных сегментов (PMode), вываливается на операции
    Код (Text):
    1. mov cr0, eax
    .

    Ассемблерный код:
    Код (Text):
    1. .386p
    2.  
    3. public _PMode
    4.  
    5. code   segment para public use16
    6. assume  cs:code
    7.  
    8. ;УКАЗАНИЕ "SYSCALL" ВМЕСТО "pascal" НЕ ПОМОГЛО
    9. _PMode  proc pascal near
    10. ; определить линейный адрес GDT
    11.         xor     eax, eax
    12.         mov   ax, cs
    13.         shl     eax, 4
    14.         lea     edx, GDT
    15.         add     eax, edx
    16. ; заполнить GDTR физическими адресами GDT
    17.         mov     dword ptr CS:GDTR+2, eax
    18.         push    ds                ; запомнить сегмент кода
    19. ; перейти в защищенный режим
    20.         cli                       ; запретить прерывания
    21.         lgdt    fword ptr cs:GDTR ; загрузить GDT
    22.         mov     eax, 1            ;
    23.         mov     CR0, eax          ; защищенный режим разрешен
    24. ; загрузить все сегментные регистры дескриптором с лимитом 4 Гб
    25.         mov     ax, 8             ; 8 - селектор нашего дескриптора
    26.         mov     ds, ax
    27.         mov     es, ax
    28.         mov     fs, ax
    29.         mov     gs, ax            ; снять ограничения с сегмента gs
    30.         xor     eax, eax          ;
    31.         mov     CR0, eax          ; перейти в реальный режим
    32.         sti                       ; разрешить другие прерывания
    33.         pop     ds
    34.         ret
    35.  
    36. GDT     dq      0, 8F92000000FFFFh; глобальная дескрипторная таблица:
    37. GDTR    dw      16, 0, 0          ; регистр таблицы глобальных дескрипторов:
    38. _PMode  endp
    39.  
    40. code ends
    41.  
    42. end
    Код в cpp:
    Код (Text):
    1. #include
    2. ....
    3.  
    4. #pragma inline
    5.  
    6. extern "C" void PMode (void);
    7.  
    8. void Enable_A20 (void)
    9. {
    10.         asm push    ax
    11.         asm in      al, 92h
    12.         asm or      al, 02h
    13.         asm out     92h, al
    14.         asm pop     ax
    15. }
    16.  
    17. void Disable_A20  (void)
    18. {
    19.         asm push    ax
    20.         asm in      al, 92h
    21.         asm and     al, 02h
    22.         asm out     92h, al
    23.         asm pop     ax
    24. }
    25.  
    26. unsigned char  Check_Safety (void)
    27. {
    28.         unsigned short XXX;
    29.         asm smsw    XXX        // прочитать слово состояния процессора
    30.                                           //(копирует младшие 16 бит регистра CR0 в ХХХ)
    31.         asm mov     ax, XXX
    32.  
    33.         if (XXX==1)            // проверяем состояние:
    34.                 return 1;        // если 1 - процессор в защищеном режиме
    35.  
    36.         asm mov     ax, 4300h  // проверить наличие XMS
    37.         asm int     2Fh              // прерывание мультиплексора
    38.         // (запрос на доступ к НМА)
    39.         // если Himem.sys загружен то 64K в НМА
    40.         // заняты и регистр ax принимает значение
    41.         // ax = 4A02h (выделить часть НМА)
    42.         asm shr     ax, 6       // сдвиг вправо на 6 бит
    43.         asm and     ax, 2      // проверить наличие Himem.sys
    44.         // если 2 - Himem.sys установлен
    45.         // если 0 - все OK
    46.         XXX = 0;
    47.         asm mov     XXX, ax
    48.         return  XXX;
    49. }
    50.  
    51. int main ()
    52. {
    53. .....
    54.         s = Check_Safety ();
    55.         if ( s != 0 )
    56.                   exit (0);
    57.         Enable_A20 ();//работает
    58.         PMode ();
    59. .....
    60.         Disable_A20();//работает
    61. .....
    62. }
     
  2. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    обычно делают
    Код (Text):
    1. mov eax, cr0
    2. or eax, 1
    3. mov cr0, eax
    и
    Код (Text):
    1. mov eax, cr0
    2. and eax, 0xFFFFFFFE
    3. mov cr0, eax
    в GDTR лимит должен быть на 1 меньше, т. е 15
    попробуй посмотреть весь сгенерированный код в целом
     
  3. lvccgd

    lvccgd New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    8
    все, работает... просто указал линкеру -ml (large model)... всем спасибо за внимание