; Le code de la deuxieme tache (pour etudier la commutation de taches) ; Auteur: Benoit Papillault ; Creation: Dimanche 6 Mars 1997 ; Derniere modification: Vendredi 25 Avril 1997 .386p include pm.inc include tss.inc include hexa32.inc MEM_VIDEO equ 0B800h ATTRIBUTS equ 0A0h public le_tss_v86 data segment public use16 m_tache_v86 dw 20*2 dw 12 db 1ah,'La tache v86 s',27h,'execute...',0 le_tss_v86 tss <> bitmap_v86 db io_range+1 dup (0) marge db 100 dup (0) v86_cs dw ? v86_ds dw ? v86_es dw ? v86_fs dw ? v86_gs dw ? v86_ss dw ? v86_sp dw ? data ends flag_vm equ 20000h code16 segment public use16 assume cs:code16 assume ds:data public init_tss_v86 init_tss_v86 proc near push ax push ds push cx push di push es ; on initialise le segment de donnee mov ax,data mov ds,ax mov es,ax ; on initialise tous a zero mov cx,io_range+size tss+1 mov di,offset le_tss_v86 cld xor al,al rep stosb mov byte ptr ds:le_tss_v86[io_range+size tss],-1 mov word ptr ds:le_tss_v86[66h],68h ; on initialise la valeur des registres de segments (lorsque l'on passera ; en mode v86) mov ax,cs mov ds:v86_cs,ax mov ax,ds mov ds:v86_ds,ax mov ax,es mov ds:v86_es,ax mov ax,fs mov ds:v86_fs,ax mov ax,gs mov ds:v86_gs,ax mov ax,ss mov ds:v86_ss,ax mov ax,sp sub ax,50 ; pour tester => marge de securite mov ds:v86_sp,ax pop es pop di pop cx pop ds pop ax ret init_tss_v86 endp public tache_v86 tache_v86 proc far mov ebp,esp mov ax,MEM_VIDEO mov es,ax xor edi,edi mov di,cs mov byte ptr es:[0],'X' mov byte ptr es:[1],ATTRIBUTS mov byte ptr es:[2],'V' mov byte ptr es:[3],ATTRIBUTS mov byte ptr es:[4],'8' mov byte ptr es:[5],ATTRIBUTS ; pour tester mov eax,[ebp] mov ebx,[ebp+4] mov ecx,[ebp+8] mov edi,[ebp+12] ; mov ebp,xxx fault: ; int 0 ; iretd => exception 13, recuperation ; iret => exception 13, recuperation ; ret => exception 13, recuperation ; retf => exception 13, recuperation mov byte ptr es:[6],'6' mov byte ptr es:[7],ATTRIBUTS iretd tache_v86 endp code16 ends .386p code32 segment public use32 assume cs:code32 public init_tss_v86_32 init_tss_v86_32 proc near push eax push ds mov ax,data32_sel mov ds,ax mov eax,esp sub eax,100 mov ds:[le_tss_v86].tss_esp0,eax mov ds:[le_tss_v86].tss_esp1,eax mov ds:[le_tss_v86].tss_esp2,eax xor eax,eax mov ax,ss mov ds:[le_tss_v86].tss_ss0,ax mov ds:[le_tss_v86].tss_ss1,ax mov ds:[le_tss_v86].tss_ss2,ax mov eax,cr3 mov ds:[le_tss_v86].tss_cr3,eax mov ds:[le_tss_v86].tss_eip,offset code16:tache_v86 ; pushfd ; pop eax ; or eax,flag_vm or 07000h ; l'image du FLAGS doit avoir le bit VM=1 (bit 17) ; on met aussi le bit NT=1 (bit 14) mov eax,27002h mov ds:[le_tss_v86].tss_eflags,eax mov ds:[le_tss_v86].tss_eax,eax mov ds:[le_tss_v86].tss_ecx,eax mov ds:[le_tss_v86].tss_edx,eax mov ds:[le_tss_v86].tss_ebx,eax mov ds:[le_tss_v86].tss_esp,esp mov ds:[le_tss_v86].tss_ebp,eax mov ds:[le_tss_v86].tss_esi,eax mov ds:[le_tss_v86].tss_edi,eax mov ax,ds:[v86_es] mov ds:[le_tss_v86].tss_es,ax mov ax,code16 mov ds:[le_tss_v86].tss_cs,ax mov ax,ds:[v86_ss] mov ds:[le_tss_v86].tss_ss,ax mov ax,ds:[v86_ds] mov ds:[le_tss_v86].tss_ds,ax mov ax,ds:[v86_fs] mov ds:[le_tss_v86].tss_fs,ax mov ax,ds:[v86_gs] mov ds:[le_tss_v86].tss_gs,ax xor ax,ax mov ds:[le_tss_v86].tss_ldt,ax pop ds pop eax ret init_tss_v86_32 endp public appel_tache_v86 appel_tache_v86 proc near call init_tss_v86_32 ; mov ax,tss_v86_sel ; mov fs,ax => exception 13, c'est normal, cf la doc du Pentium: ; toute tentative de charger un selecteur de TSS dans un registre ; de segment provoquera l'exception 13 mov eax,offset u_ret mov dl,0 mov dh,1 call WriteHexa4_32 mov ebp,esp ; call far tss_v86_sel:tache2 db 9ah dd 0 dw tss_v86_sel u_ret: mov eax,22222222h mov dl,60 mov dh,23 call WriteHexa4_32 ret appel_tache_v86 endp code32 ends end