DOS: Hello from protect mode
; Программа, выводящая текст "Hello word!" из защищенного режима.

format MZ
entry codeseg:start

;===============================================================[Служебные макросы]====
; Запрещает маскируемые и немаскируемые прерывания
macro disable_interrupts {
        cli              ; запретить прерывания
        in      al, 70h  ; индексный порт CMOS
        or      al, 80h  ; установка бита 7 в нем запрещает NMI
        out     70h, al
}

; Разрешает маскируемые и немаскируемые прерывания
macro enable_interrupts {
        in      al, 70h  ; индексный порт CMOS
        and     al, 7Fh  ; сброс бита 7 отменяет блокирование NMI
        out     70h, al
        sti              ; разрешить прерывания
}

; Устанавливает флаг PE
macro set_PE {
        mov     eax, cr0 ; прочитать регистр CR0
        or      al, 1    ;  установить бит PE
        mov     cr0, eax ; с этого момента мы в защищенном режиме
}

; Сбрасывает флаг PE
macro clear_PE {
        mov     eax, cr0 ; прочитать регистр CR0
        and     al, 0FEh ; сбросить бит PE
        mov     cr0, eax ; с этого момента мы в реальном режиме
}


;====================================================================[Сегмент кода]====
segment codeseg
use16
start:
        ; Подготовить сегментные регистры
        push    cs
        pop     ds                 ; DS - сегмент данных (и кода) нашей программы
        push    0xB800
        pop     es                 ; ES - сегмент видеопамяти

        disable_interrupts         ; запретить прерывания
        set_PE                     ; перейти в защищенный режим

        ; Установка текстового режима 3 (80x25, цвета 16/8, адрес видео буфера 0xB800)
        mov     ax, 3
        int     10h
        xor     di, di             ; ES:DI - начало видеопамяти

        ; Вывод на экран пробелов с атрибутом 1Ah
        mov     ax, 1A20h          ; пробел с атрибутом 1Ah
        mov     cx, length_1       ; заполнить этим символом начало экрана
        rep stosw

        ; Вывод на экран строки 'Hello word!'
        mov     si, message        ; DS:SI - выводимый текст
        mov     cx, message_size   ; количество символов
        rep movsw                  ; вывод текста

        ; Вывод на экран пробелов с атрибутом 1Ah
        mov     ax, 1A20h          ; пробел с атрибутом 1Ah
        mov     cx, length_2       ; заполнить этим символом остаток экрана
        rep stosw

        clear_PE                   ; переключиться в реальный режим
        enable_interrupts          ; разрешить прерывания

        ; Подождать нажатия любой клавиши
        mov     ah, 0
        int     16h

        ; Выход
        mov     ax, 0x4C00
        int     21h

;==========================================================================[Данные]====
; текст сообщения с атрибутом после каждого символа для прямого вывода на экран
message db      'H',1Ah, 'e',1Ah, 'l',1Ah, 'l',1Ah, 'o',1Ah, ',',1Ah, ' ',1Ah
        db      'w',1Ah, 'o',1Ah, 'r',1Ah, 'l',1Ah, 'd',1Ah, '!',1Ah
message_size = ($ - message)/2               ; его длина в словах
length_1   = ((80*25)-message_size) shr 1    ; количество пробелов до текста
length_2   = (80*25)-length_1-message_size   ; количество пробелов после текста

;======================================================================================



Последнее обновление : 1 марта 2008
Hosted by uCoz