Assembler - язык неограниченных возможностей


Переключение задач - часть 3


PM_seg segment para public "CODE" use32 assume cs:PM_seg

; таблица глобальных дескрипторов GDT label byte db 8 dup(0) GDT_flatDS db 0FFh,0FFh,0,0,0,10010010b,11001111b,0 GDT_16bitCS db 0FFh,0FFh,0,0,0,10011010b,0,0 GDT_32bitCS db 0FFh,0FFh,0,0,0,10011010b,11001111b,0 GDT_32bitSS db 0FFh,0FFh,0,0,0,10010010b,11001111b,0 ; сегмент TSS задачи 0 (32-битный свободный TSS) GDT_TSS0 db 067h,0,0,0,0,10001001b,01000000b,0 ; сегмент TSS задачи 1 (32-битный свободный TSS) GDT_TSS1 db 067h,0,0,0,0,10001001b,01000000b,0 gdt_size = $ - GDT gdtr dw gdt_size-1 ; размер GDT dd ? ; адрес GDT ; используемые селекторы SEL_flatDS equ 001000b SEL_16bitCS equ 010000b SEL_32bitCS equ 011000b SEL_32bitSS equ 100000b SEL_TSS0 equ 101000b SEL_TSS1 equ 110000b

; сегмент TSS_0 будет инициализирован, как только мы выполним переключение ; из нашей основной задачи. Конечно, если бы мы собирались использовать ; несколько уровней привилегий, то нужно было бы инициализировать стеки TSS_0 db 68h dup(0) ; сегмент TSS_1. В него будет выполняться переключение, так что надо ; инициализировать все, что может потребоваться: TSS_1 dd 0,0,0,0,0,0,0,0 ; связь, стеки, CR3 dd offset task_1 ; EIP ; регистры общего назначения dd 0,0,0,0,0,stack_l2,0,0,0B8140h ; (ESP и EDI) ; сегментные регистры dd SEL_flatDS,SEL_32bitCS,SEL_32bitSS,SEL_flatDS,0,0 dd 0 ; LDTR dd 0 ; адрес таблицы ввода-вывода

; точка входа в 32-битный защищенный режим PM_entry: ; подготовить регистры xor еах,еах mov ax,SEL_flatDS mov ds,ax mov es,ax mov ax,SEL_32bitSS mov ebx,stack_l mov ss,ax mov esp,ebx ; загрузить TSS задачи 0 в регистр TR mov ax,SEL_TSS0 ltr ax ; только теперь наша программа выполнила все требования к переходу ; в защищенный режим xor еах,еах mov edi,0B8000h ; DS:EDI - адрес начала экрана task_0: mov byte ptr ds:[edi],al ; вывести символ AL на экран ; дальний переход на TSS задачи 1 db 0EAh dd 0 dw SEL_TSS1 add edi,2 ; DS:EDI - адрес следующего символа inc al ; AL - код следующего символа, cmp al,80 ; если это 80, jb task_0 ; выйти из цикла ; дальний переход на процедуру выхода в реальный режим db 0EAh dd offset RM_return dw SEL_16bitCS




Начало  Назад  Вперед