[asm] Przełączanie w Tryb chroniony

0

Witam, nie jestem zapalonym niskopoziomowcem, studiuję na WAT, pasjonuję się Java, a Assemblera nie kumam w ogóle od zawsze. Mam do opisania krótki tekst-kod dotyczący przełączania procesora w tryb protected, będę bardzo wdzięczny za każde wyjaśnienie o co tu się rozchodzi.

.386p

            stack    segment    stack use16
                    dd    100 dup(0)
            stack    ends

            data segment use16
            gdt        dd    0
                    dd    0
            code_desc    dd    0000ffffh
                    dd    00cf9a00h
            data_desc    dd    0000ffffh
                    dd    00cf9200h
            ret_desc    dd    0000ffffh
                    dd    00cf9a00h
            gdt_label    label    fword
            gdt_limit    dw    4*8-1
            gdt_base    dd    ?
            protected_code_address    dd    0
                        dw    08h
            data ends

            code segment para public use16 'code'
            assume cs:code,ds:data,ss:stack
    start:
            mov    ax,data
            mov    ds,ax
                ; setup gdt
            mov    eax,0
            mov    ax,data
            shl    eax,4
            add    eax,offset gdt
            mov    gdt_base,eax
                ; runtime fixup of far jump into pmode
            mov    eax,0
            mov    ax,code32
            shl    eax,4
            add    eax,offset protected_code
            mov    protected_code_address,eax
                ; runtime fixup for far jump back to rmode
            mov    eax,0
            mov    ax,code32
            mov    es,ax
            mov    word ptr es:[4],18h
            
            cli
            db    66h
            lgdt    gdt_label
            smsw    ax
            or    ax,1
            lmsw    ax
            jmp    next
    next:        jmp    fword ptr protected_code_address
    ret_real:    smsw    ax
            and    ax,0fffeh
            lmsw    ax
            jmp    far ptr s16
    s16:
                    sti
            mov    ax,4c00h
            int    21h
    code        ends

    code32        segment    use32
            assume    cs:code32
    sto:
            jmp    far ptr ret_real
    protected_code:
            mov    ax,10h
            mov    ds,ax
            mov    ebx,0b8000h
            mov    ax,0741h
            mov    ecx,80*25
    st1:
            mov    [ebx],ax
            add    ebx,2
            loop    st1
            jmp    sto
            
    code32        ends
            end    start
0
M.G. napisał(a)

Witam, nie jestem zapalonym niskopoziomowcem, studiuję na WAT, pasjonuję się Java, a Assemblera nie kumam w ogóle od zawsze. Mam do opisania krótki tekst-kod dotyczący przełączania procesora w tryb protected, będę bardzo wdzięczny za każde wyjaśnienie o co tu się rozchodzi.

A znasz podstawy asemblera i działanie procesora w trybie rzeczywistym i chronionym ?
Wiesz co to segmenty (kodu, danych, stosu), deskryptory, adresacje i ich rodzaje ?
Bez tego to będą tylko komentarze do kodu.

Gdybyś nie wiedział to tutaj wszystko dokładnie jest opisane. (sciagnij sobie pdf-a i poczytaj) Intel Architecture Software Developer's Manual Volume 3: System Programming

Cosik Ci tu dopiszę ale, lepiej będzie jak poczytasz manuala.

.386p

            stack    segment    stack use16
                    dd    100 dup(0)
            stack    ends

            data segment use16
                                            ;globalna tablica deskrypotrow
            gdt        dd    0    ;pusty deskryptor (dummy)                   
                    dd    0
            code_desc    dd    0000ffffh   ;deskryptor segmentu kodu
                    dd    00cf9a00h
            data_desc    dd    0000ffffh    ;deskrypotr segmentu danych
                    dd    00cf9200h
            ret_desc    dd    0000ffffh    ;2-gi deskryptor segmentu kodu 
                    dd    00cf9a00h          ; 
            gdt_label    label    fword     ;koniec tablicy deskryptorow
            gdt_limit    dw    4*8-1       ;rozmiar talicy deskrypotorow - 1
            gdt_base    dd    ?             ;adres bazowy tablicy deskryptorow
            protected_code_address    dd    0    ;adres bazowy segmentu kodu dla trybu chronionego
                        dw    08h
            data ends

            code segment para public use16 'code'
            assume cs:code,ds:data,ss:stack
    start:
            mov    ax,data
            mov    ds,ax
                ; setup gdt     ;obliczanie adresu fizycznego GDT (global descriptor table)
            mov    eax,0
            mov    ax,data
            shl    eax,4
            add    eax,offset gdt
            mov    gdt_base,eax

                ; runtime fixup of far jump into pmode
            mov    eax,0            ;obliczanie adresu fizycznego poczatka segmentu kodu dla trybu chronionego
            mov    ax,code32
            shl    eax,4
            add    eax,offset protected_code
            mov    protected_code_address,eax
                ; runtime fixup for far jump back to rmode
            mov    eax,0            
            mov    ax,code32
            mov    es,ax
            mov    word ptr es:[4],18h
            
            cli                ;wylaczenie przerwan
            db    66h        ;preifx do instrukcji 32 bitowych (w niektorych kompilatorach nie trzeba tego dawać) 
            lgdt    gdt_label       ;zaladowanie rejestru GDT z pamieci 
            smsw    ax            
            or    ax,1
            lmsw    ax           ; wlacz tryb chroniony (ustawianie najmlodzsego bitu rejestru CR0)
            jmp    next          ;skocz do kodu trybu chronioego
    next:        jmp    fword ptr protected_code_address   ;zaladjuj CS:EIP z pamieci 
    ret_real:    smsw    ax
            and    ax,0fffeh
            lmsw    ax         ;wylacz tryb chroniony (zerowanie najmlodzego bitu rejestru CR0)
            jmp    far ptr s16
    s16:
                    sti               ;wlacz przerwania
            mov    ax,4c00h      ;przerwij program
            int    21h
    code        ends

    code32        segment    use32
            assume    cs:code32
    sto:
            jmp    far ptr ret_real
    protected_code:
            mov    ax,10h      
            mov    ds,ax                  ;selektor 2 (wskazuje na data_des w GDT)
            mov    ebx,0b8000h        ;adres pamieci video (tryb tekstowy)
            mov    ax,0741h            ; znak zamalowanego kołka w jakims tam kolorze (znak-atrybut)
            mov    ecx,80*25           ;petla od rozmiar ekranu do 0
    st1:
            mov    [ebx],ax            ;zapisz znak i atrybut do pamieci video
            add    ebx,2                ; zwieksz adres o 2 bajty
            loop    st1                    ;petla 
            jmp    sto                   ;skocz do wyjscia w tryb rzeczywisty
            
    code32        ends
            end    start

1 użytkowników online, w tym zalogowanych: 0, gości: 1