[asm] artykuł z 4p o pisaniu OSów - pamięć

0

Witam. Czytałem artykuł ze strony: Pisanie systemów operacyjnych - tryb rzeczywisty

Nie żebym chciał pisać OS tylko chciałem poczytać coś ASM i zrozumieć. Bardzo interesujący ten tekst tylko jak zwykle nie rozumiem pewnych spraw:

1. Pierwsza to taka konstrukcja w ASM:

times 510 - ($ - start) db 0

domyślam się że times 510 ma powtórzyć db 0 razy 510 ale nie rozumiem ($ - start). Pewnie etykieta start jest dla kompilatora jakąś liczbą, ale ten znaczek dolara to już kompletnie utrudnia zrozumienie. O co chodzi?

2. Drugi problem jest z pamięcią i dyrektywą org:

BIOS ładuje pierwsze 512 bajtów z dysku do pamięci pod adresem 07C0:0000 i skacze w to miejsce

Ok. to rozumiem.

;tutaj zaczyna się nasz program
org 7C00h

Jak mówi inne źródło:

org mówi kompilatorowi, że kod będzie znajdował się pod tym adresem (segment 07C0 * 16 = adres 7C00), ułatwia kompilatorowi określenie adresów różnych etykiet (w tym danych) znajdujących się w programie

To jeszcze mogę przełknąć, ale bootloader skacze do 0800:0000 a tam jest kernel który zaczyna się tak:

;pamiętasz, kernela załadowaliśmy pod adres 0800h:0000h, wiec
;zaczynamy od 0000h
org 0000h  

Tutaj się poddaje. W takim razie, czemu nie org 8000h? Jak jest różnica między tymi dwoma przypadkami?

3. Jaka jest wartość rejestru CS w bootloaderze, a jaka w kernelu?

Przepraszam za pewnie trywialne pytania. Po prostu jest to trochę trudne do wyobrażenia dla amatora.

0

Ja tu w jednej kwestii.

piechnat napisał(a)

1. Pierwsza to taka konstrukcja w ASM:

times 510 - ($ - start) db 0

domyślam się że times 510 ma powtórzyć db 0 razy 510 ale nie rozumiem ($ - start). Pewnie etykieta start jest dla kompilatora jakąś liczbą, ale ten znaczek dolara to już kompletnie utrudnia zrozumienie. O co chodzi?
Nie spotkalem sie z dyrektywa 'times' ale zapewne to tak jak 'dup' dla tasm. Niestety, co kompilator to inna skladnia.

'$' oznacza adres w miejscu wstawienia dolara.
prosty przyklad:

napis db 'ala ma kota'
dlugosc db $-napis

napis i dlugosc to etykiety czyli liczby dla assemblera oznaczajace adres w pamieci [pierwszego bajtu dla ciagow] dlatego jesli odejmiemy adres etykiety 'dlugosc' od adresu 'napis' to otrzymana roznica bedzie akurat dlugoscia tego ciagu.

0

dzięki [browar] to wszystko tłumaczy...
gdyby ktoś coś jeszcze napisał jak to jest z tym org i segmentem kodu w przykładzie...

0

Jak bios zaladuje bootloadera pod 07C0:0000 to z reguly cs ma wartosc 0, ale zamiast ustawiac cs'a na 7C0 mozna ustawic orga na 7C00 bo 07C0:0000 i 0000:7C00 to to samo.

Skaczac do kernela podajesz adres 0800:0000, pierwsza jego czesc to oczywiscie segment ktory od tej pory bedzie w CS, jakbys teraz ustawil orga na 8000 to wyszlo by ci 0800:8000.

0
times 510 - ($ - start) db 0

BIOS ładuje pierwsze 512 bajtów z dysku do pamięci pod adresem 07C0:0000 i skacze w to miejsce

Dokładnie chodzi o to, by wypełnić 512 bajtów po kodzie samymi zerami. $ oznacza obecne miejsce; start oznacza w tym przypadku początek kodu. Jeśli odejmiesz ($-start) otrzymasz długość kodu.

(510 - długość kodu) oznacza, ile miejsca po kodzie należy wypełnić zerami. To właśnie robi ta dyrektywa: w tym miejscu pamięci dopisz (510 - długość kodu) razy [times] definicję bajtu o wartości 0 [db 0].

0

dziękuję za odpowiedzi [browar] teraz to ma wszystko ręce i nogi :-)
(oczywiście niezauważyłem wcześniej że pod tym adresem na dole jest osobna tabela dla JMP w której jest cenna informacja [glowa] )

0

Witam!
Wyjaśnię ci, o co chodzi z tymi org-ami, bo troche czasu siedzę już w tym temacie.

W bootloaderze, ktory jest ladowany pod adres 0000:7C00h, jest org 7C00h, ponieważ jest to 1 segment pamięci, a offset &C00 hexadecymalnie. W trybie rzeczywistym segmenty maja po 64kb. W rejestrze CS jest numer segmentu, postaci liczby, która po pomnożeniu przez 16 i dodaniu do niej adresu już wewnętrznego, w tym wypadku 7C00h, daje rzeczywisty adres, pod jakim znajdują się dane, pomijając segmentację.
W drugim przykładzie jest adres 0800:0000h, więc w rejestrze CS będzie 0800h, a aktualna pozycja IP to 0, stąd org 0000h.
Segmentacja pomaga w adresowaniu tak, że możesz załadować dane w dowolny segment, i będą one automatycznie miały przeliczone adresy, ponieważ rejestry segmentowe będą miały numer segmentu, służący do przeliczenia adresu.

Aha i sorka, jeżeli niezrozumiale cos napisalem.
Wojtek 'Bluebat'

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