Простейшее использование видеопамяти

Тема в разделе "WASM.BEGINNERS", создана пользователем Piroman17, 31 июл 2006.

  1. Piroman17

    Piroman17 New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2006
    Сообщения:
    7
    Задача такая: в PM (адресатция сегментная), надо вывести строчку на экран. Вроде задача простая, но ничего не получается.
    Так же я смотрел http://www.wasm.ru/article.php?article=pipm08, почему то тоже
    строку не выводит. (У меня сделано аналогично).
    ПОМОГИТЕ ВЧЁМ ОШИБКА ИСХОДНОГО КОДА http://www.wasm.ru/article.php?article=pipm08.
     
  2. Piroman17

    Piroman17 New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2006
    Сообщения:
    7
    Извеняюсь, проблема не в выводе строки, а в команде
    Код (Text):
    1. lgdt    fword ptr GDTR  ;здесь происходит RESET
    2. ...
    3. GDTR    dw    GDT_size-1      ; 16-битнvй лимит GDT
    4.            dd    ?                    ; здесь будет 32-битнvй линейнvй адрес GDT
    На этой команде проц почему то делает RESET!
    Если знаете в чём проблема поскажите плиз!
     
  3. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Ты уверен, что падение происходит именно там? lgdt команда относительно безобидная. Здесь подобный код пробегал, возможно у тебя аналогичная проблема?

    Если нет -- приведи весь код.
     
  4. Piroman17

    Piroman17 New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2006
    Сообщения:
    7
    Я не уверен что здесь, скорее всего где то дальше:)

    Привожу:

    Код (Text):
    1.     .386p                                           ; разрешить привилегированнvе инструкции i386
    2.  
    3. ; T++і+=T і+-L (для Real Mode)
    4. ; ---------------------------------------------------------------------------------------------------------
    5. RM_CODE   segment   para public 'CODE' use16
    6.     assume     CS:RM_CODE,SS:RM_STACK
    7. @@start:
    8.  
    9. ; очистка экрана:
    10.     mov             AX,3
    11.     int             10h
    12.  
    13.     in    AL,92h
    14.     or    AL,2
    15.     out    92h,AL
    16.  
    17. ; вvчисляем линейнvй адрес метки ENTRY_POINT (точка входа в заиеннvй режим):
    18.     xor    EAX,EAX        ; обнуляем регистра EAX
    19.     mov    AX,PM_CODE      ; AX = номер сегмента PM_CODE
    20.     shl    EAX,4        ; EAX = линейнvй адрес PM_CODE
    21.     add    EAX,offset ENTRY_POINT     ; EAX = линейнvй адрес ENTRY_POINT
    22.     mov    dword ptr ENTRY_OFF,EAX    ; сохраняем его в переменной
    23.  
    24. ; теперь надо вvчислить линейнvй адрес GDT (для загрузки регистра GDTR):
    25.     xor    EAX,EAX
    26.     mov    AX,RM_CODE      ; AX = номер сегмента RM_CODE
    27.     shl    EAX,4        ; EAX = линейнvй адрес RM_CODE
    28.     add    AX,offset GDT      ; теперь EAX = линейнvй адрес GDT
    29.  
    30. ; линейнvй адрес GDT кладем в заранее подготовленнуі переменнуі:
    31.     mov    dword ptr GDTR+2,EAX
    32.  
    33. ; собственно, загрузка регистра GDTR:
    34.    lgdt    fword ptr GDTR
    35.  
    36. ; запрет маскируемvх прерvваний:
    37.     cli
    38.  
    39. ; запрет немаскируемvх прерvваний:
    40.     in    AL,70h
    41.     or    AL,80h
    42.     out    70h,AL
    43.  
    44. ; переклічение в заиеннvй режим:
    45.     mov    EAX,CR0
    46.     or    AL,1
    47.     mov    CR0,EAX
    48.  
    49. ; загрузить новvй селектор в регистр CS
    50.     db    66h        ; префикс изменения разрядности операнда
    51.     db    0EAh        ; опкод командv JMP FAR
    52. ENTRY_OFF   dd    ?        ; 32-битное смеение
    53.     dw    00001000b      ; селектор первого дескриптора (CODE_descr)
    54.  
    55. ; TL+TLЈL +T++LT-=-- -+TііLіT+і+T:
    56. GDT:
    57. ; нулевой дескриптор (обязательно должен присутствовать в GDT!):
    58. NULL_descr  db    8 dup(0)
    59. CODE_descr  db    0FFh,0FFh,00h,00h,00h,10011010b,11001111b,00h
    60. DATA_descr  db    0FFh,0FFh,00h,00h,00h,10010010b,11001111b,00h
    61. VIDEO_descr     db              0FFh,0FFh,00h,80h,0Bh,10010010b,01000000b,00h
    62. GDT_size  equ     $-GDT        ; размер GDT
    63.  
    64.  
    65. GDTR    dw    GDT_size-1      ; 16-битнvй лимит GDT
    66.         dd    ?               ; здесь будет 32-битнvй линейнvй адрес GDT
    67. RM_CODE         ends
    68. ; ---------------------------------------------------------------------------------------------------------
    69.  
    70. ; T++і+=T і+-L (для Protected Mode)
    71. ; ---------------------------------------------------------------------------------------------------------
    72. PM_CODE   segment   para public 'CODE' use32
    73.     assume  CS:PM_CODE, DS:PM_DATA
    74. ENTRY_POINT:
    75. ; загрузим сегментнvе регистрv селекторами на соответствуіие дескрипторv:
    76.           mov         AX,00010000b                ; селектор на второй дескриптор (DATA_descr)
    77.           mov         DS,AX                       ; в DS его
    78.           mov         AX,00011000b                ; селектор на третий дескриптор (VIDEO_descr)
    79.           mov         ES,AX                       ; а этого в ES
    80.  
    81.           xor            ESI,ESI                     ; обнуляем ESI
    82.           mov            SI,PM_DATA                  ; SI = номер сегмента PM_DATA
    83.           shl            ESI,4                       ; ESI = линейнvй адрес сегмента PM_DATA
    84.           add         ESI,offset message          ; ESI = линейнvй адрес строки message
    85.                 xor            EDI,EDI                     ; EDI = позиция на экране (относительно 0B8000h)
    86.           mov         ECX,mes_len                 ; длина текста в ECX
    87.  
    88. ; вvвод на экран:
    89.           rep            movsb                       ; DS:ESI (наше сообение) -> ES:EDI (видеопамять)
    90.           jmp            $                           ; погружаемся в вечнvй цикл
    91. PM_CODE          ends
    92. ; ---------------------------------------------------------------------------------------------------------
    93.  
    94.  
    95.  
    96. ; T++і+=T -L==-- (для Protected Mode)
    97. ; ---------------------------------------------------------------------------------------------------------
    98. PM_DATA          segment        para public 'DATA' use32
    99.     assume         CS:PM_DATA
    100.  
    101. ; сообение, которое мv будем вvводить на экран (оформим его в виде блока повторений irpc):
    102. message:
    103. irpc            mes,           <Congratulations! We are in PM! Now you MUST Press RESET...                >
    104.                 db             '&mes&',0Dh
    105. endm
    106. mes_len         equ            $-message       ; длина в байтах
    107. PM_DATA         ends
    108. ; ---------------------------------------------------------------------------------------------------------
    109.  
    110. ; T++і+=T TT+іL (для Real Mode)
    111. ; ---------------------------------------------------------------------------------------------------------
    112. RM_STACK       segment          para stack 'STACK' use16
    113.          db          100h dup(?)                     ; 256 байт под стек - это даже много
    114. RM_STACK       ends
    115. ; ---------------------------------------------------------------------------------------------------------
    116.  
    117.                 end          @@start