?
These exemple the program which install PC in the protected mode and realize two tasks.
;name file pm.asm
; tasm /m pm.asm
; tlink /x /3 pm.obj
.386p
Stack_seg segment para stack 'STACK'
stack_task1 db 32h dup(?)
stack1 = $-stack_task1
stack_task2 db 32h dup(?)
stack2 = $-stack_task1
Stack_seg ends
code_seg segment para public 'CODE' use16
assume cs:code_seg, ds:data_seg, ss:Stack_seg
start:
push data_seg
pop ds
mov ax, code_seg
shl eax, 4
mov word ptr g_code + 2, ax ;mladwij
shr eax, 16
mov byte ptr g_code + 4, al ; starwij
mov ax, data_seg
shl eax, 4
mov word ptr g_pmc+2, ax
shr eax, 16
mov byte ptr g_pmc+4, al
mov eax, 0h
mov ax, data_seg
shl eax, 4
push eax
add eax, offset gdt
mov dword ptr gdtr+2, eax
lgdt fword ptr gdtr
pop eax
push eax
add eax, offset TSS_0
mov word ptr g_TSS0+2, ax
shr eax, 16
mov byte ptr g_TSS0+4, al
pop eax
add eax, offset TSS_1
mov word ptr g_TSS1+2, ax
shr eax, 16
mov byte ptr g_TSS1+4, al
BIOS of adress 0040h:0067h
push ds
mov ax, 40h
mov ds, ax
mov ds:67h, offset Real_return
mov ds:69h, cs
pop ds
cli
mov al, 8fh
out 70h, al
jmp a1
a1:
mov al, 05h
out 71h, al
mov eax, cr0
or al, 1
mov cr0, eax
db 66h
db 0EAh ; kod far jmp
dd offset a2 ; metku a2
dw 18h ; segment code
LABEL Real_return FAR
mov ax, data_seg
mov ds, ax
mov es, ax
mov ax, stack_seg
mov bx, stack1
mov ss, ax
mov sp, bx
sti
in al, 70h
and al, 07FH
out 70h,al
mov ah, 4Ch
int 21h
code_seg ends
data_seg segment para public 'CODE' use32
assume cs:data_seg
; GDT
gdt label byte
g_0 db 8 dup(0) ; nulivoj deskriptor
g_data db 0FFh, 0FFh, 0,0,0, 10010010b, 01001111b, 0 ; dannix segment
g_code db 0FFh, 0FFh, 0,0,0, 10011010b, 0, 0 ; code segment
g_pmc db 0FFh, 0FFh, 0,0,0, 10011010b, 01001111b, 0 ; code segment
g_stack db 0FFh, 0FFh, 0,0,0, 10010010b, 01001111b, 0 ; Stack segment
g_TSS0 db 067h, 0, 0,0,0, 10001001b, 01000000b, 0 ; TSS0 segment
g_TSS1 db 067h, 0, 0,0,0, 10001001b, 01000000b, 0 ; TSS1 Segment
; GDT razmer
gdt_size = $-gdt
; GDT register
gdtr dw gdt_size-1 ; GDT limit
dd ? ; GDT base
TSS_0 db 68h dup(0)
TSS_1 dd 0,0,0,0,0,0,0,0 ; Link; Stack 0 - 2
dd offset task_1 ; IP - opinting to 'TASK_1'
dd 0,0,0,0,0
dd stack2 ; SP - stack2
dd 0,0 ; BP, SI
dd 0B8000h ; DI - Video memory start
dd 0 ; ES
dd 18h ; CS - Code segment selector (PM)
dd 20h ; SS - 32b Stack selector
dd 8h ; DS - Data Segment selector
dd 0,0
dd 0 ; LDTR
dd 0
a2:
mov eax, 0h
mov ax, 8h ; Data Segment Selector
mov ds, ax
mov es, ax
mov ax, 20h ; stack selector
mov ebx, stack1 ;
mov ss, ax
mov esp, ebx
mov eax, 0h
mov cx, 0h
mov edi, 0B8000h ; adress video memory
mov ax, 28h ; TSS_0 Selector
ltr ax ; load v TR
task_0:
mov ah, 07h
mov al, 'a'
mov word ptr ds:[edi - 2],ax ;
db 0EAh
dd 0
dw 30h ; TSS_1 selector
add edi, 2
inc cx
cmp cx, 20 ;
jne task_0
null_idt dw 0
dw 0
db 0
db 0
dw 0
lidt [fword ptr null_idt]
int 3h
wait_reset:
hlt
jmp wait_reset
task_1:
mov ah,07h
mov al, 'b'
mov word ptr ds:[edi + 160],ax
add edi,2
pop bx
db 0EAh
dd 0
dw 28h ; TSS2 Selector
mov ecx, 00100000h ; pause
loop $
jmp task_1
data_seg ends
end start