sw sprawozdanie lab2 v3(1)

background image

Instytut Teleinformatyki i Automatyki

LABORATORIUM

SYSTEMÓW WBUDOWANYCH

Sprawozdanie z ćwiczenia laboratoryjnego nr 2

TEMAT:

Tryby pracy procesorów firmy Intel

Prowadzący ćwiczenia:

dr inż. Artur Arciuch
mgr inż. Waldemar Szylberg

background image

WSTĘP TEORETYCZNY

Zasadniczo istnieją 4 tryby pracy procesora 386+:

tryb rzeczywisty (real mode)

tryb chroniony (protected mode)

tryb wirtualny V86 - kombinacja 2 powyższych

ryb nierzeczywisty (tzw. unreal mode - procesor pracuje w RM, ale można używać adresowania 32-
bitowego; to jest raczej sztuczka programistyczna)

Każdy procesor z rodziny x86 po rozpoczęciu pracy działa w trybie rzeczywistym. W takim trybie procesor
"widzi" tylko pierwszy megabajt RAM'u i dopiero system operacyjny (typu Windows lub Linux) przełącza
go w protected mode podczas bootowania. W dodatku pamięć w RM jest podzielona na segmenty po 64kB
co np. bardzo utrudnia używanie w programach tablic o rozmiarach przekraczających ten limit.

Tryb chroniony stwarza możliwość użycia naprawdę dużej ilości pamięci (do 4 GB na 386, w
przeciwieństwie do dotychczasowego 1 MB). Nie trzeba już używać powolnych EMS i XMS by dostać się
do pamięci rozszerzonej. Ponieważ rozmiar segmentu nie jest ograniczony do 64kB, można w praktyce
wyeliminować rejestry segmentowe i operować w tzw. trybie flat - jest to ważne w przypadku kiedy
potrzebujemy dużej prędkości działania programu, DS jest zajęty a my nie chcemy prefixowac ES'em,
FS'em itd. Inne zastosowanie: operacje na buforach ekranowych przy dużych rozdzielczościach i/lub dużej
liczbie kolorów, które to bufory wymagają więcej niż 64kB pamięci.

W trybie chronionym wszystkie przerwania BIOS lub DOS'a, których używaliśmy, przykładowo, do
obsługi plików, staja się bezużyteczne bo nie mogą działać w Protected Mode (oczywiście można to obejść
poprzez chwilowe wychodzenie z trybu chronionego do trybu rzeczywistego na czas wykonywania
przerwania,

ale

nie

jest

to

już

takie

łatwe).

Nie można także beztrosko używać samomodyfikujacego się kodu - czytanie lub zapis w segmencie
wykonywalnym

spowoduje

wygenerowanie

wyjątku

GP.

Wprowadzenie mechanizmów ochrony pamięci wymagało podjęcia specjalnych środków. Każdy segment
(kod, dane, stos) opisywany jest przez tzw. deskryptor. Zadaniem deskryptora jest określenie BAZY
SEGMENTU (jego fizycznego adresu w pamięci, np. dla bufora VGA adres bazowy wynosi 0A0000h),
LIMITU (rozmiaru segmentu - może wynosić od 1B do 4GB) oraz jego TYPU/FLAG (czy segment zawiera
dane,

kod,

etc.)

Technicznie rzecz biorąc deskryptor jest to 8-bajtowa struktura danych, która rezyduje gdzieś w pamięci
operacyjnej i ma następujący format:

background image

Znaczenie

kolejnych

bajtów

jest

takie:

0,

1

-

młodsze

słowo

długości

segmentu

(limitu)

2,

3

-

młodsze

słowo

adresu

bazowego

segmentu

4

-

młodszy

bajt

starszego

słowa

adresu

bazowego

5

-

flagi

segmentu

6

-

starszy

półbajt

limitu

i

tzw.

flagi

dostępu

7

-

starszy

bajt

starszego

słowa

adresu

bazowego

Rozmiar segmentu w protected mode może być dowolny (a wiec nie tylko 64kB, ale także każda inna
wielkość od 1B do 4GB). Jak wynika z opisu limit w deskryptorze jest to liczba 20-bitowa (8 + 8 + 4) co
daje maksymalnie 1048576 czyli 1MB.

Adres bazowy to 32-bitowa liczba wyznaczająca początek segmentu w pamięci. Zazwyczaj pisząc typowy
DOS'owy extender bazę możemy wyznaczyć poprzez pomnożenie przez 16 numeru segmentu, w którym
znajduje się nasz kod 32-bitowy. Wartość ta będzie dla nas bardzo ważna jeśli będziemy chcieli np. dobrać
się do pamięci ekranu.

Pojawia się pytanie: skąd procesor wie, gdzie w pamięci znajduje się dany deskryptor? Postanowiono
grupować deskryptory w tablice tzn. kolejno następujące po sobie deskryptory.

Tablica ta zawiera 3 deskryptory: tzw. Null Descriptor, deskryptor segmentu kodu oraz deskryptor
segmentu danych. Ten pierwszy pojawia się tylko w tablicach GDT i zawsze zawiera same zera.

Wyróżniamy 3 typy tablic: GDT (Globalna Tablica Deskryptorów), LDT (Lokalna Tablica Deskryptorów;
używana przez pojedynczy proces w systemie) oraz IDT (Tablica Deskryptorów Przerwań).

Procesor musi wiedzieć, gdzie takie tablice się znajdują i dlatego dysponuje specjalnymi rejestrami, które
zawierają 32-bitowy fizyczny adres danej tablicy oraz jej długość. Są 3 rejestry: GDTR (przechowuje adres
i długość GDT) oraz, analogicznie, LDTR i IDTR.

Kod programu przełączający procesor w tryb protected:

Comment |

Program przełączający w tryb protected

|

.386p

CR EQU 0DH

LF EQU 0AH

;-------------------------------------------------------------------------

background image

; globalna tablica deskryptorów

segment_GDT SEGMENT use16

dq 0 ; poz. 0 - deskryptor zerowy (nieużywany)
dq 0 ; poz. 1 - selektor 0008H

dq 0 ; poz. 2 - selektor 0010H - segment 'nowe_dane'
dq 0 ; poz. 3 - selektor 0018H

dq 0 ; poz. 4 - selektor 0020H
dq 0 ; poz. 5 - selektor 0028H

dq 0 ; poz. 6 - selektor 0030H
dq 0 ; poz. 7 - selektor 0038H

dq 0 ; poz. 8 - selektor 0040H
dq 0 ; poz. 9 - selektor 0048H

dq 0 ; poz.10 - selektor 0050H

dq 0 ; poz.11 - selektor 0050H
dq 0 ; poz.12 - selektor 0050H

dq 0 ; poz.13 - selektor 0050H
dq 0 ; poz.13 - selektor 0050H

segment_GDT_end LABEL byte

segment_GDT ENDS

;-------------------------------------------------------------------

; tablica deskryptorów przerwań

segment_IDT SEGMENT use16
; Tablica zawiera furtki prowadzące do procedur obsługi przerwa¤

; i wyjątków o numerach 0 - 127. Pola 'offset' w kolejnych furtkach
; zawierać będą liczby 0, 7, 14, 21, itd.

xpom=0

REPT 128
dw xpom ; offset

dw 6 SHL 3 ; selektor
db 0 ; licznik

db 10000110B ; bajt dostępu
dw 0 ; rezerwa

xpom=xpom+7
ENDM

segment_IDT_end LABEL byte
segment_IDT ENDS

;-------------------------------------------------------------------------

; segment danych dla trybu chronionego - segment ten wskazywany jest przez
; selektor 2 * 8 = 0010H

nowe_dane SEGMENT use16
kom4 db 'Procesor pracuje w trybie chronionym '

db ' - wciśnięcie dowolnego klawisza spowoduje wyjście'

db

' - naciśniecie ESC spowoduje zakończenie programu',0

kom5 db 'Nierozpoznane polecenie', 0
txt_czas db 'czas',13,0

bufor_klaw db 128 dup (?) ; bufor klawiatury
indeks_klaw dw 0

indeks_zeg dw

0

ekran_x db 0 ; wskaźnik nr kolumny do zapisu na ekranie

ekran_y db 0 ; wskaźnik nr wiersza do zapisu na ekranie
; tablica do przekodowania kodów pozycji na kody ASCII

pozycja

dw 160*12+80

x

dw 1

y

dw 1

tabl_przekA db 0, 1BH, '1234567890-=',08H, 09H ; kody 0 - 15

db 'qwertyuiop[]', 0DH, 0, 'as' ; kody 16 - 31
db 'dfghjkl;''`',0,'\zxcv' ; kody 32 - 47

db 'bnm,./',0,'*',0,' ',0 ; kody 48 - ...

background image

nowe_dane_end LABEL byte
nowe_dane ENDS

;-------------------------------------------------------------------------

nowy_stos SEGMENT use16 ; stos dla trybu chronionego
pstos dw 2048 dup (?)

nowy_stos_end LABEL byte
nowy_stos ENDS

;---------------------------------------------------------------------------

stos_RM SEGMENT use16 stack ; stos dla trybu rzeczywistego
dw 256 dup (?)

stos_RM ENDS
;---------------------------------------------------------------------------

ekran SEGMENT use16 at 0B800H ; segment imitujący pamięć ekranu

db 4000 dup (?)
ekran_end LABEL byte

ekran ENDS

;---------------------------------------------------------------------------
rozkazy SEGMENT use16 ; rozkazy programu

; obszary 48-bitowe potrzebne do ładowania rejestrów GDTR oraz IDTR
zaw_GDTR dp 0

zaw_IDTR dp 0
rm_idt LABEL qword ; wskaźnik do tabl. wekt. przerwań (tryb rzecz.)

dw 03FFH ; wielkość tablicy IDT
dd 0

czy_koniec db 0
komunikat1 db 'Wciśnij dowolny klawisz aby przełączyć w Protected Mode',CR, LF, '$'

komunikat2 db 'Real Mode', CR, LF, '$'
komunikat3

db 'Zakończono program',CR,LF,'$'

zadania

dw zy1,zy2,zy3

komunikat1z db 'Zadanie1 w RealMode',CR,LF,'$'

komunikat2z db 'Zadanie2 w RealMode',CR,LF,'$'
komunikat3z

db 'Zadanie3 w RealMode',CR,LF,'$'

;----------------------------------------------------------------------

; kod wykonywany ponownie w trybie rzeczywistym bezpośrednio przed

; zakończeniem wykonywania programu
ASSUME cs:rozkazy

ptt3:
lidt cs:rm_idt ; podanie adresu tabl. wektorów przerwań

; dla trybu rzeczywistego
mov ax, SEG stos_RM ; tworzenie stosu dla trybu rzecz.

mov ss, ax
mov sp, 80H

sti
call czysc_ekran

push cs
pop ds

mov dx, OFFSET komunikat2
mov ah, 09H

int 21H ; wyświetlenie komunikatu
mov al,byte ptr [czy_koniec]

cmp

al,0

je

pocz;

pelny_koniec:

mov dx, OFFSET komunikat3

mov ah, 09H
int 21H

mov ax,4C00H ; zakończenie wykonywania programu
int 21H

;----------------------------------------------------------------------
; kod wykonywany w trybie rzeczywistym bezpośrednio po uruchomieniu programu

pocz: nop

background image

mov

al,34h

out

43h,al

mov

al,0ffh

out

40h,al

mov

al,0ffh

out

40h,al

; Wyświetlanie komunikatów o przeznaczeniu programu i oczekiwanie

; na potwierdzenie dalszego wykonywania programu
call czysc_ekran

jmp cd_przyg
; czyszczenie ekranu - przewiniecie okna o zero wierszy

czysc_ekran PROC near
mov ah, 06 ; przewiniecie okna

mov al, 0 ; zero wierszy
mov bh, 07 ; atrybut

mov ch, 0 ; współrzędne okna
mov cl, 0 ; lewy górny róg

mov dh, 24 ; prawy dolny róg
mov dl, 79

int 10H
mov ah, 2 ; ustawienie kursora w górnym lewym rogu ekranu

mov dl, 0
mov dh, 0

mov bh, 0
int 10H

ret
czysc_ekran ENDP

zy1:
mov dx, OFFSET komunikat1z

mov ah, 09H
int 21H

ret

zy2:
mov dx, OFFSET komunikat2z

mov ah, 09H
int 21H

ret

zy3:

mov dx, OFFSET komunikat3z
mov ah, 09H

int 21H

ret

cd_przyg:

push cs
pop ds

dalej_RM:

call [zadania]

call

[zadania+2]

call

[zadania+4]

mov dx, OFFSET komunikat1

mov ah, 09H
int 21H ; wyświetlenie komunikatu

mov ah, 07H ; oczekiwanie na naciśniecie klawisza
int 21H

cmp al,27
je pelny_koniec; naciśnięto Esc

call czysc_ekran;

; tworzenie deskryptorów w globalnej tablicy przerwa¤ (na razie wszystkie
; pola w deskryptorach zawierają zera)

; we wszystkich deskryptorach bajt 6 (bity G, D, 0, AVL, rozmiar 19 - 16)
; pozostawiany jest bez zmian (zawiera zero)

; ASSUME ds:segment_GDT
mov ax, SEG segment_GDT

mov ds, ax ; ładowanie rejestru DS

background image

; tworzenie deskryptora na pozycji 2 w GDT - deskryptor ten opisuje

; segment 'nowe_dane'
mov bx, 2 * 8 ; offset w segmencie segment_GDT

mov word PTR ds:[bx], OFFSET nowe_dane_end - 1 ; rozmiar segmentu
mov ax, SEG nowe_dane

movzx eax, ax ; zerowanie starszej części EAX
shl eax, 4 ; w EAX adres bazowy segmentu

mov ds:[bx]+2,ax ; adres bazowy 15 - 0
rol eax, 16 ; zamiana połówek EAX

mov ds:[bx]+4, al ; adres bazowy 23 - 16
mov ds:[bx]+7, ah ; adres bazowy 31 - 24

mov byte PTR ds:[bx]+5, 10010010B ; bajt dostępu
; tworzenie deskryptora na pozycji 3 w GDT - deskryptor ten opisuje

; segment 'ekran'
mov bx, 3 * 8 ; offset w segmencie segment_GDT

mov word PTR ds:[bx], OFFSET ekran_end - 1 ; rozmiar segmentu
mov ax, SEG ekran

movzx eax, ax ; zerowanie starszej części EAX
shl eax, 4 ; w EAX adres bazowy segmentu

mov ds:[bx]+2,ax ; adres bazowy 15 - 0
rol eax, 16 ; zamiana połówek EAX

mov ds:[bx]+4, al ; adres bazowy 23 - 16
mov ds:[bx]+7, ah ; adres bazowy 31 - 24

mov byte PTR ds:[bx]+5,10010010B ; bajt dostępu
; tworzenie deskryptora na pozycji 6 w GDT - deskryptor ten opisuje

; segment 'obsl_int'
mov bx, 6 * 8 ; offset w segmencie segment_GDT

mov word PTR ds:[bx], OFFSET obsl_int_end - 1 ; rozmiar segmentu
mov ax, SEG obsl_int

movzx eax, ax ; zerowanie starszej części EAX
shl eax, 4 ; w EAX adres bazowy segmentu

mov ds:[bx]+2,ax ; adres bazowy 15 - 0
rol eax, 16 ; zamiana połówek EAX

mov ds:[bx]+4, al ; adres bazowy 23 - 16
mov ds:[bx]+7, ah ; adres bazowy 31 - 24

mov byte PTR ds:[bx]+5,10011010B ; bajt dostępu
; tworzenie deskryptora na pozycji 7 w GDT

mov bx, 7 * 8 ; offset w segmencie segment_GDT
mov word PTR ds:[bx], OFFSET nowy_stos_end - 1 ; rozmiar segmentu

mov ax, SEG nowy_stos
movzx eax, ax ; zerowanie starszej części EAX

shl eax, 4 ; w EAX adres bazowy segmentu
mov ds:[bx]+2,ax ; adres bazowy 15 - 0

rol eax, 16 ; zamiana połówek EAX
mov ds:[bx]+4, al ; adres bazowy 23 - 16

mov ds:[bx]+7, ah ; adres bazowy 31 - 24
mov byte PTR ds:[bx]+5,10010010B ; bajt dostępu

; tworzenie deskryptora na pozycji 8 w GDT
mov bx, 8 * 8 ; offset w segmencie segment_GDT

mov word PTR ds:[bx], OFFSET rozkazy_end - 1 ; rozmiar segmentu
mov ax, SEG rozkazy

movzx eax, ax ; zerowanie starszej części EAX
shl eax, 4 ; w EAX adres bazowy segmentu

mov ds:[bx]+2,ax ; adres bazowy 15 - 0
rol eax, 16 ; zamiana połówek EAX

mov ds:[bx]+4, al ; adres bazowy 23 - 16
mov ds:[bx]+7, ah ; adres bazowy 31 - 24

mov byte PTR ds:[bx]+5,10011010B ; bajt dostępu
; tworzenie deskryptora na pozycji 9 w GDT - deskryptor używany jako

; atrapa przy przejsciu z trybu chronionego do rzeczywistego (w tym
; przypadku adres bazowy w deskryptorze nie ma żadnego znaczenia)

mov bx, 9 * 8 ; offset w segmencie segment_GDT
mov word PTR ds:[bx],0FFFFH ; wymagany rozmiar segmentu

; bajt dostępu musi opisywać segment danych (fikcyjny), w którym:
; P=1, ED=0, W=1

mov byte PTR ds:[bx]+5,10010010B ; bajt dostępu
; tworzenie deskryptora na pozycji 10 w GDT - deskryptor ten opisuje

; segment kodu 'roz_zak', który jest wykonywany bezpośrednio przed

background image

; przejściem do trybu rzeczywistego (pole "wielkosc" = FFFFH)
mov bx, 10 * 8 ; offset w segmencie segment_GDT

mov word PTR ds:[bx], 0FFFFH ; rozmiar segmentu
mov ax, SEG roz_zak

movzx eax, ax ; zerowanie starszej części EAX
shl eax, 4 ; w EAX adres bazowy segmentu

mov ds:[bx]+2,ax ; adres bazowy 15 - 0
rol eax, 16 ; zamiana połówek EAX

mov ds:[bx]+4, al ; adres bazowy 23 - 16
mov ds:[bx]+7, ah ; adres bazowy 31 - 24

mov byte PTR ds:[bx]+5,10011010B ; bajt dostępu

; tworzenie deskryptora na pozycji 11 w GDT
mov bx, 8 * 11 ; offset w segmencie segment_GDT

mov word PTR ds:[bx], OFFSET zad1_end- 1 ; rozmiar segmentu
mov ax, SEG zad1

movzx eax, ax ; zerowanie starszej części EAX
shl eax, 4 ; w EAX adres bazowy segmentu

mov ds:[bx]+2,ax ; adres bazowy 15 - 0
rol eax, 16 ; zamiana połówek EAX

mov ds:[bx]+4, al ; adres bazowy 23 - 16
mov ds:[bx]+7, ah ; adres bazowy 31 - 24

mov byte PTR ds:[bx]+5,10011010B ; bajt dostępu
; tworzenie deskryptora na pozycji 11 w GDT

mov bx, 8 * 12 ; offset w segmencie segment_GDT
mov word PTR ds:[bx], OFFSET zad2_end- 1 ; rozmiar segmentu

mov ax, SEG zad2
movzx eax, ax ; zerowanie starszej części EAX

shl eax, 4 ; w EAX adres bazowy segmentu
mov ds:[bx]+2,ax ; adres bazowy 15 - 0

rol eax, 16 ; zamiana połówek EAX
mov ds:[bx]+4, al ; adres bazowy 23 - 16

mov ds:[bx]+7, ah ; adres bazowy 31 - 24
mov byte PTR ds:[bx]+5,10011010B ; bajt dostępu

; tworzenie deskryptora na pozycji 11 w GDT
mov bx, 8 * 13 ; offset w segmencie segment_GDT

mov word PTR ds:[bx], OFFSET zad3_end- 1 ; rozmiar segmentu
mov ax, SEG zad3

movzx eax, ax ; zerowanie starszej części EAX
shl eax, 4 ; w EAX adres bazowy segmentu

mov ds:[bx]+2,ax ; adres bazowy 15 - 0
rol eax, 16 ; zamiana połówek EAX

mov ds:[bx]+4, al ; adres bazowy 23 - 16
mov ds:[bx]+7, ah ; adres bazowy 31 - 24

mov byte PTR ds:[bx]+5,10011010B ; bajt dostępu

; tworzenie deskryptora na pozycji 11 w GDT
mov bx, 8 * 14 ; offset w segmencie segment_GDT

mov word PTR ds:[bx], OFFSET shed_end- 1 ; rozmiar segmentu
mov ax, SEG shed

movzx eax, ax ; zerowanie starszej części EAX
shl eax, 4 ; w EAX adres bazowy segmentu

mov ds:[bx]+2,ax ; adres bazowy 15 - 0
rol eax, 16 ; zamiana połówek EAX

mov ds:[bx]+4, al ; adres bazowy 23 - 16
mov ds:[bx]+7, ah ; adres bazowy 31 - 24

mov byte PTR ds:[bx]+5,10011010B ; bajt dostępu

; przygotowanie do wykonania rozkazu LGDT (ładowanie rejestru GDTR)

mov ax, OFFSET segment_GDT_end ; rozmiar tablicy GDT
mov word PTR cs:zaw_GDTR+0, ax

mov ax, SEG segment_GDT ; adres (segmentowy) globalnej
; tablicy deskryptorów

movzx eax, ax ; zerowanie starszej części EAX

background image

shl eax, 4 ; w EAX adres bazowy segmentu
mov dword PTR cs:zaw_GDTR+2, eax

; przygotowanie do wykonania rozkazu LIDT (ładowanie rejestru IDTR)
mov ax, OFFSET segment_IDT_end ; rozmiar tablicy GDT

mov word PTR cs:zaw_IDTR+0, ax
mov ax, SEG segment_IDT ; adres (segmentowy) tablicy

; deskryptorów przerwań
movzx eax, ax ; zerowanie starszej części EAX

shl eax, 4 ; w EAX adres bazowy segmentu
mov dword PTR cs:zaw_IDTR+2, eax

cli ; zablokowanie przyjmowania przerwań
lgdt cs:zaw_GDTR ; ładowanie rejestru GDTR

lidt cs:zaw_IDTR ; ładowanie rejestru IDTR
; przelaczenie do trybu chronionego

mov eax, CR0
or eax, 1

mov CR0, eax
jmp next ; oczyszczenie kolejki rozkazów

; oczekujących na wykonanie
next: nop

; Skok daleki do następnej instrukcji - instrukcja ta powoduje zapisanie
; także rejestru CS w taki sposób, że selektor 0040H (czyli 8 * 8)

; wpisany do CS wskazuje na deskryptor w tablicy GDT, opisujący
; niniejszy segment. Zatem będzie dalej wykonywany kod z tego samego

; segmentu, ale rejestr CS zawiera teraz selektor, a nie adres segmentu.
; Rozkaz skoku dalekiego jest kodowany bajtowo ponieważ

; w asemblerze brak potrzebnego trybu adresowania 'jmp far PTR ca1'
DB 0EAH

DW tryb_PM
dw 8 * 8 ; selektor wskazujący na deskryptor

; segmentu 'rozkazy'
tryb_PM: nop

;-------------------------------------------------------------------------
; przeprogramowanie układu 8259, tak by przerwanie z zegara (nr 8 w trybie

; rzeczywistym) było związane z nr 32, przerwanie z klawiatury (nr 9)
; - z nr 33, itd.

call przestaw_8259
; inicjalizacja stosu - segment stosu dla trybu chronionego

; opisany jest przez deskryptor 7
mov ax, 7 * 8

mov ss, ax
mov sp, 1000

; inicjalizacja rejestrow DS, ES, FS, GS - wpisanie selektora wskazującego na
; segment 'nowe_dane'

mov ax, 2 * 8
mov ds, ax

mov es, ax
mov fs, ax

mov gs, ax
; call zeruj_bufor_klaw ; zerowanie bufora klawiatury

sti ; włączenie przyjmowania przerwań
; wyswietlenie komunikatu "Procesor pracuje w trybie chronionym"

mov bx, OFFSET kom4
call wyswietl

;-----------------------------------------------------------------------
; Główna pętla przyjmowania zleceń od użytkownika w trybie chronionym

; sprawdź, czy w buforze klawiatury jest kod Enter (0DH) lub Esc (1BH)
czytaj_od_nowa:

mov ax, 2 * 8
mov ds, ax

; mov dx, 0 ; używany do sterowania wyświetlaniem
DB 0EAH

DW str1
dw 8 * 14


db 0

klaw14:

mov cx, ds:indeks_klaw

jcxz klaw14 ; skok, gdy pusty bufor

mov

ds:indeks_klaw,0

background image

cmp

cx,001Bh

jne

klaw14b;

push ds
mov

ax,8*8

mov

ds,ax

mov

al,1

mov byte ptr[czy_koniec],al
pop ds

klaw14b:

; przygotowanie do powrotu do trybu rzeczywistego - skok daleki

; do segmentu kodu (kodowany bajtowo, ponieważ
; w asemblerze brak potrzebnego trybu adresowania 'jmp far PTR przelacz_do_RM'

DB 0EAH
DW przelacz_do_RM

dw 10 * 8 ; nr pozycji deskryptora wskazującego
; segment rozkazowy

; przeprogramowanie układu 8259, tak by przerwanie z zegara (nr 8 w trybie

; rzeczywistym) było związane z nr 32, przerwanie z klawiatury (nr 9)
; - z nr 33, itd.

przestaw_8259 PROC
mov al,11H

out 20H,al ; ładowanie ICW1 (d4=1 - znacznik
; wskazujący, ze programujemy ICW1

; bit d0=1 - znacznik ,ze wystąpi ICW4
mov al,32

out 21H,al ; ustawienie bazowego wektora przerwań
; (ustawienie ICW2)

mov al,4
out 21H,al ; ICW3 - d2=1 - tryb niebuforowany, 8259 master

mov al,1
out 21H,al ; ICW4 - d0=1 - potwierdzenie ICW2 jako wektora

; przerwań
ret

przestaw_8259 ENDP

;--------------------------------------------------------------------------
; wyswietlanie tekstu na ekranie - tekst zawarty jest w segmencie danych

; dla trybu chronionego (selektor 0010H), a offset podany jest w BX
; tekst wyswietlany jest w wierszu wskazanym przez zmienna ekran_y

; ekran_x db 0 ; wskaźnik nr kolumny do zapisu na ekranie
; ekran_y db 0 ; wskaźnik nr wiersza do zapisu na ekranie

wyswietl PROC

; selektor 0010H (2 * 8) wskazuje deskryptor segmentu danych dla trybu
; chronionego ('nowe_dane')

push ds
push es

mov ax, 2 * 8
mov ds, ax

mov ax, 3 * 8 ; selektor pamięci ekranu
mov es,ax

mov al, 160
mul byte PTR ds:ekran_y ; w AX adres ekranu do zapisu

mov di, ax
mov ah,7 ; atrybut wyświetlania

ptl_kom: mov al,ds:[bx] ; pobranie kolejnego znaku komunikatu
or al, al

jz koniec_wysw ; bajt zerowy wskazuje koniec tekstu
mov es:[di],ax ; przesłanie znaku do pamięci ekranu

inc bx ; inkrementacja BX

background image

inc di ; inkrementacja DI
inc di ; inkrementacja DI

jmp ptl_kom
koniec_wysw:

mov al, ds:ekran_y
inc al

cmp al, 23
jae przesun_ekran

mov ds:ekran_y, al
zak_wysw:

pop es
pop ds

ret
; przesuwanie calego ekranu o jeden wiersz w gore

przesun_ekran:
dec al

mov ds:ekran_y, al
mov ax, 3 * 8 ; selektor pamięci ekranu

mov ds, ax
mov es, ax

mov cx, 2000 - 240
mov si, 160

mov di, 0
cld

rep movsw
jmp zak_wysw

wyswietl ENDP

rozkazy_end LABEL near

rozkazy ENDS

;----------------------------------------------------------------------

roz_zak SEGMENT use16

ASSUME cs:roz_zak

; rozkazy zawarte w tym segmencie wykonywane są bezpośrednio przed

; przejściem z trybu chronionego do trybu rzeczywistego

przelacz_do_RM: nop

; przywrócenie tradycyjnych numerów przerwa¤

cli ; wyłączenie przyjmowania przerwa¤

mov al,11H

out 20H,al

mov al,8

out 21H,al

mov al,4

out 21H,al

background image

mov al,1

out 21H,al ; ładowanie ICW4

mov al,0BCH

out 21H,al

; przed przejściem do trybu rzeczywistego rejestry segmentowe powinny

; zawierać selektory wskazujące fikcyjny segment danych (zob. opis

; deskryptora 10)

mov ax, 9 * 8 ; deskryptor na pozycji nr 9 wskazuje

; fikcyjny segment danych

mov ds,ax

mov es,ax

mov ss,ax

mov fs, ax

mov gs, ax

; zerowanie bitu PG w CR0

mov eax, CR0

and eax, 7FFFFFFFH

mov CR0, eax

; zerowanie rejestru CR3

mov eax, 0

mov CR3, eax

; zerowanie bitu PE w rejestrze CR0 (włączenie trybu rzeczywistego)

mov eax, CR0

and eax,0FFFFFFFEH

mov CR0, eax

jmp far PTR ptt3

roz_zak ENDS

background image

;-----------------------------------------------------------------------

obsl_int SEGMENT use16

ASSUME cs:obsl_int

; Każdemu przerwaniu odpowiadają 3 rozkazy zajmujące łącznie 7 bajtów.

; Pierwszy z tych rozkazów zapamiętuje rejestr CX na stosie, zaś następny

; wpisuje do CX nr przerwania lub wyjątku, co pozwala, w dalszej części

; procedury obsługi, zidentyfikował przyczynę przerwania i ewentualnie

; podjął działania właściwe dla zaistniałego zdarzenia.

xpom=0
REPT 128

push cx ; nr przerwania lub wyjątku
mov cx,xpom

jmp proc_obsl
xpom=xpom+1

ENDM

ORG $+128 ; wymusza by nie występowały JMP SHORT
proc_obsl: sti

push ds
push es

push ax
push bx

push dx
push si

cmp cx,33 ; czy przerwanie z klawiatury

je klawisze

sti
jmp

przeskocz_klaw

; obsluga przerwania z klawiatury

klawisze:

in al,60H ; odczyt kodu pozycji klawisza
xor ah,ah ; zerowanie rejestru AH

push ax ; przechowanie rejestru AX
in al,61H

or al,82H
out 61H,al

and al,7FH
out 61H,al

pop ax ; odtworzenie rejestru AX
cmp al, 57

ja przeskocz_klaw ; nie sa obsługiwane klawisze o kodach
; pozycji > 55

mov bx, 2 * 8 ; selektor do segmentu 'nowe_dane'
mov ds, bx

mov si, OFFSET tabl_przekA
mov bl, al

xor bh, bh
mov al, ds:[si+bx]

klaw2:
; dopisanie znaku do bufora

cli
; mov bx, OFFSET bufor_klaw

; add bx, ds:indeks_klaw
; mov ds:[bx], al

background image

dalej:

mov word PTR ds:indeks_klaw,ax

mov

bx,3*8

mov

es,bx

mov bx,ds:pozycja

mov

es:[bx],al

jmp przeskocz_klaw

przeskocz_klaw:

mov al, 20H
out 20H, al ; end of interrupt (OCW2)

pop si
pop dx

pop bx
pop ax

pop es
pop ds

pop cx
iret

obsl_int_end LABEL near

obsl_int ENDS
shed SEGMENT use16

ASSUME cs:shed
z1 db 0

z2 db 0
z3 db 0

nz db 0
nzb db 0

str1:

DB 0EAH

DW s

dw 8 *11 ; selektor wskazujący na deskryptor

za2:

DB 0EAH

DW ss1

dw 8 *12 ; selektor wskazujący na deskryptor

za3:

DB 0EAH

DW sss

dw 8 *13 ; selektor wskazujący na deskryptor

konza:

DB 0EAH

DW klaw14

dw 8 *8 ; selektor wskazujący na deskryptor

; segmentu 'rozkazy'

shed_end label near
shed ENDS

zad1 SEGMENT use16

ASSUME cs:zad1
s:

push ds;
mov ax,8*3

mov ds,ax
mov al,'a'

mov bx,160*3
mov byte ptr ds:[bx],al

pop ds

DB 0EAH

background image

DW za2

dw 8 * 14 ; selektor wskazujący na deskryptor

; segmentu 'rozkazy'

zad1_end label near
zad1 ENDS

zad2 SEGMENT use16
ASSUME cs:zad2

ss1:

push ds;
mov ax,8*3

mov ds,ax
mov al,'b'

mov bx,160*4+2
mov byte ptr ds:[bx],al

pop ds
DB 0EAH

DW za3

dw 8 * 14 ; selektor wskazujący na deskryptor

; segmentu 'rozkazy'
zad2_end label near

zad2 ENDS

zad3 SEGMENT use16
ASSUME cs:zad3

sss:

push ds;

mov ax,8*3
mov ds,ax

mov al,'c'
mov bx,160*5+4

mov byte ptr ds:[bx],al
pop ds

DB 0EAH

DW konza

dw 8 * 14 ; selektor wskazujący na deskryptor

; segmentu 'rozkazy'

zad3_end label near
zad3 ENDS

END pocz


Document Outline


Wyszukiwarka

Podobne podstrony:
sw sprawozdanie lab2 v4(1)
Badanie wyplywu cieczy ze zbior sprawozdanie z lab2 id 631079 (2)
Sprawozdanie lab2
sprawozdanie lab2?bugger(2)12345678
Sprawozdanie lab2
PBI Chłap Krupiński Sprawozdanie Lab2
Sprawozdanie LAB2
Sprawozdanie Lab2 AIM
Mechanika płynów sprawozdanie z lab2
Sprawozdanie lab2, Elektrotechnika
Badanie wypływu cieczy ze zbiornika Mechanika płynów sprawozdanie z lab2
Sprawozdanie lab2 Żołądkiewicz&Szatara
Sprawozdanie Lab2
Badanie wyplywu cieczy ze zbior sprawozdanie z lab2 id 631079 (2)
sw wejsciowka lab2(1)
sprawozdanie lab2
Sprawozdanie Lab2
2013 08 23 FPA 5000 SW HW releases V3

więcej podobnych podstron