выход из РМ

Тема в разделе "WASM.ASSEMBLER", создана пользователем 0136, 3 дек 2008.

  1. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Привет, обьясните почему не получается нормально выйти из РМ, файл прикрепил, виснет и не пойму почему?
     
  2. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    А вот почти такой же код, комп ребутиться после выхода из РМ в дос. Кто то скажет почему?

    .386p
    stk segment STACK
    dw 100h dup (0)
    size_stk = $-stk
    stk ends

    data segment use16
    ;0писание GDT

    ;слово 3 (старшее):
    ;биты 15–8: биты 31–24 базы
    ;бит 7: бит гранулярности (0—лимит в байтах, 1—лимит в 4-килобайтных единицах) (G)
    ;бит 6: бит разрядности (0/1—16-битный/32-битный сегмент) (D)
    ;бит 5: 0 (X)
    ;бит 4: зарезервировано для операционной системы (U)
    ;биты 3–0: биты 19–16 лимита

    ;слово 2:
    ;бит 15: бит присутствия сегмента (P)
    ;биты 14–13: уровень привилегий дескриптора (DPL)
    ;бит 12: тип дескриптора (0—системный, 1—обычный) (S)
    ;биты 11–9: тип сегмента (TYPE)
    ;бит 8: бит обращения (А)
    ;биты 7–0: биты 23–16 базы

    ;слово 1: биты 15–0 базы

    ;слово 0 (младшее): биты 15–0 лимита

    ;пустой дескриптор
    zero_descr db 8 dup (0)
    ; дескрипторы для инициализации
    ; дескриптор кода №8
    code_descr dw 0 ; предел 15-0
    dw 0 ; базовый адрес 15-0
    db 0 ; базовый адрес 23-16
    ;pDPLsTypeA
    db 10011010b ; права доступа AR
    db 0 ; предел 19-16 и GDXU
    db 0 ; базовый адрес 31-24
    ;дескриптор данных №16
    data_descr dw 0 ; предел 15-0
    dw 0 ; базовый адрес 15-0
    db 0 ; базовый адрес 23-16
    ;pDPLsTypeA
    db 10010010b ; права доступа AR
    db 0 ; предел 19-16 и GDXU
    db 0 ; базовый адрес 31-24
    ;дескриптор стека №24
    stk_descr dw 0 ; предел 15-0
    dw 0 ; базовый адрес 15-0
    db 0 ; базовый адрес 23-16
    ;pDPLsTypeA
    db 10010010b ; права доступа AR
    db 0 ; предел 19-16 и GDXU
    db 0 ; базовый адрес 31-24
    ;дескриптор текстового видео буфера №32
    video_descr dw 0 ; предел 15-0
    dw 0 ; базовый адрес 15-0
    db 0 ; базовый адрес 23-16
    ;pDPLsTypeA
    db 10010010b ; права доступа AR
    db 0 ; предел 19-16 и GDXU
    db 0 ; базовый адрес 31-24

    size_gdt = $-zero_descr ; pазмер в GDT байтах

    ; операнды команды lgdt
    lgdt_size dw size_gdt-1 ; размер GDT
    lgdt_adr dd ? ; и её физический адрес

    data ends

    code segment use16
    assume cs:code, ss:stk
    start:
    mov ax, data
    mov ds, ax ; данные

    ; вычислим физ. адр. сегмента кода
    xor eax, eax
    mov ax, code
    shl eax, 4 ; теперь в eax физический адрес сегмента кода
    mov word ptr ds:code_descr+2, ax ; передадим биты 15-0 базового адреса в дескриптор
    shr eax, 16
    mov byte ptr ds:code_descr+4, al ; биты 23-16 базового адреса
    ; загрузим значение лимита сегмента и GDXU
    mov eax, 0FFFFh
    mov word ptr ds:code_descr, ax ; передадим биты 15-0 предела сегмента
    shr eax, 16
    or al, 00000000b ; установим биты GDXU=0
    mov byte ptr ds:code_descr+6, al ; передадим биты 23-16 предела и GDXU

    ; вычислим физ. адр. сегмента данных
    xor eax, eax
    mov ax, data
    shl eax, 4 ; теперь в eax физический адрес сегмента
    mov word ptr ds:data_descr+2, ax ; передадим биты 15-0 базового адреса в дескриптор
    shr eax, 16
    mov byte ptr ds:data_descr+4, al ; биты 23-16 базового адреса
    ; загрузим значение лимита сегмента и GDXU
    mov eax, 0FFFFh
    mov word ptr ds:data_descr, ax ; передадим биты 15-0 предела сегмента
    shr eax, 16
    or al, 00000000b ; биты GDXU=0
    mov byte ptr ds:data_descr+6, al ; передадим биты 23-16 предела и GDXU

    ; вычислим физ. адр. сегмента стека
    xor eax, eax
    mov ax, stk
    shl eax, 4 ; теперь в eax физический адрес сегмента
    mov word ptr ds:stk_descr+2, ax ; передадим биты 15-0 базового адреса в дескриптор
    shr eax, 16
    mov byte ptr ds:stk_descr+4, al ; биты 23-16 базового адреса
    ; загрузим значение лимита сегмента и GDXU
    mov eax, size_stk-1 ; в eax размер (минус единица)
    mov word ptr ds:stk_descr, ax ; передадим биты 15-0 предела сегмента
    shr eax, 16
    or al, 00000000b ; биты GDXU=0
    mov byte ptr ds:stk_descr+6, al ; передадим биты 23-16 предела и GDXU

    ; настроим дескриптор для текстового видеобуфера
    mov eax, 0B8000h ; 0B8000h физ. адр. текстового видеобуфера
    mov word ptr ds:video_descr+2, ax ; передадим биты 15-0 базового адреса в дескриптор
    shr eax, 16
    mov byte ptr ds:video_descr+4, al ; биты 23-16 базового адреса
    ; загрузим значение лимита сегмента и GDXU
    mov eax, 160*25-1 ; 25 строк по 160 символов, в eax размер (минус единица)
    mov word ptr ds:video_descr, ax ; передадим биты 15-0 предела сегмента
    shr eax, 16
    or al, 00000000b ; биты GDXU=0
    mov byte ptr ds:video_descr+6, al ; передадим биты 23-16 предела и GDXU

    ; вычисляется физ. адрес GDT
    xor eax, eax
    mov ax, data ; GDT находится в сегменте data
    shl eax, 4 ; физический адрес сегмента
    add ax, offset zero_descr ; физический адрес GDT

    mov dword ptr ds:lgdt_adr , eax ; сохр. физ. адреса GDT для команды lgdt
    lgdt fword ptr ds:lgdt_size ; загрузка GDTR


    ; отключить прерывания
    cli ; аппаратные

    in al,70h ; NMI
    or al,80h
    out 70h,al

    ; включаем защищённый режим
    mov eax, cr0
    or eax, 1
    mov cr0, eax ; PM=ON

    db 0EAh ; оп код команды far jmp
    dw offset PM_ON ; ip
    dw 8 ; cs=code
    PM_ON:

    ; загружаем селекторы дескрипторов в регистры
    mov ax, 16 ; селектор данных
    mov ds, ax ; ds=data
    mov ax, 24 ; селектор стека
    mov ss, ax ; ss=stk
    mov ax, 32 ; селектор видео страницы
    mov es, ax ; es=video

    mov word ptr es:[320], 0202h ; вывести смайлик

    ; выключаем защищённый режим
    ; PM = OFF
    mov eax,cr0
    and al,0FEh
    mov cr0,eax
    ;
    db 0EAh
    dw $+4
    dw code

    mov ax, cs
    mov ds, ax
    mov es, ax
    mov ax, stk
    mov bx, size_stk
    mov ss,ax
    mov sp,bx

    ; разрешить прерывания
    in al,70h ; NMI
    and al,07FH
    out 70h,al

    sti ; аппаратные

    mov ah, 9
    lea dx, mes
    int 21h
    mov ah, 4Ch
    int 21h
    mes db "hi$"

    code ends

    end start
     
  3. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Выложи плоский бинарь, который можно в Bochs загрузить. Будет намного проще найти в чем проблема.
     
  4. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Привет всем! Значит так, ошибка найдена. Проблема была в том что, после выключения сейф мода, лимит некоторых сегментных регистров был не 0FFFFh. Всё работает отлично когда лимит 0FFFFh. Удачи всем! %)