Asm x86, bootsektor i nieprzespane noce

Forum dotyczące ogólnie pojętego programowania - algorytmów, struktur danych, narzędzi programistycznych, itp - głównie w kontekście komputerów PC.
ODPOWIEDZ
Awatar użytkownika
GrzesiekG
Użytkownik
Posty: 160
Rejestracja: 11 sie 2006, 8:06
Lokalizacja: Annopol
Kontakt:

Asm x86, bootsektor i nieprzespane noce

Post autor: GrzesiekG » 19 cze 2008, 20:52

Witam!
Jak można sądzić po tytule jestem lekko powiedziawszy w desperacji, bo napisałem taki oto prościutki bootsektor na dyskietkę:

Kod: Zaznacz cały

org 7c00h
start:

	xor ax, ax ;tryb graficzny 40x25
	int 10h

	mov ah,2
	mov bh,0
	mov dx,15h
	int 10h		;ustawianie kursora
	mov bx,5
	mov ah,0eh
	mov dx, info

pisz:
	mov al, [dx] 	;invalid effective adress (wtf?)
	cmp al, "$"
	je juz		;pisanie na ekreanie za pomocą int10H
	int 10h
	add dx,1
	jmp pisz	

już:

	xor ah,ah
	int 16h
	mov bx,40h
	mov ds,bx
	mov word [ds:72h],1234h
	jmp 0ffffh:0000h

info: db "Moj system operacyjny v0.1$"
times 510 - ($ - start) db 0
dw 0aa55h
jego zadaniem jest wypisać na ekranie zbiór "info" zakończony znakiem "$" (nie użyłem int 21h, ah=9, bo DOS'a przecież nie ma!). Tak jak zaznaczyłem w opisie przy mov al, [dx] czyli przepisanie zawartości elementu tablicy "info", której to adres (offset) jest zapisany w dx, występuje wyjątek przy konpilacji: invalid effective adress. Aha, przy kożystaniu z dostępu do segmentu 0B800h występował ten sam problem z "efektywnym adresem" :evil:
Co mam robić? Kożystam z kompilatora NASM

PS. Przy okazji: dlaczego wyskakuje mi błąd jak chcę napisać: mov al, [info+bx]
gdzie bx to offset przy dostępie do tablicy "info".
Ostatnio zmieniony 20 cze 2008, 17:54 przez GrzesiekG, łącznie zmieniany 1 raz.

Awatar użytkownika
Luminofor
Użytkownik
Posty: 1373
Rejestracja: 27 lis 2007, 17:17
Lokalizacja: Polska

Post autor: Luminofor » 19 cze 2008, 21:25

Może inny kompilator? MASM jest dobry.

elemaniac
Użytkownik
Posty: 585
Rejestracja: 07 maja 2008, 17:09
Lokalizacja: Puławy
Kontakt:

Post autor: elemaniac » 20 cze 2008, 10:08

Tu jest pokazane jak stworzyć własny bootsektor w asm :
Kurs ASM
Myślę, że Ci się do czegoś przyda.

PS : Nigdy tego nie robiłem ani nie kompilowałem więc nie daję 100% pewności, że działa.

Awatar użytkownika
GrzesiekG
Użytkownik
Posty: 160
Rejestracja: 11 sie 2006, 8:06
Lokalizacja: Annopol
Kontakt:

Post autor: GrzesiekG » 20 cze 2008, 12:47

właśnie z tego kursu się uczyłem i na jego podstawie pisałem ten bootsektor

Awatar użytkownika
jejek
-
Posty: 63
Rejestracja: 12 lip 2005, 8:16
Lokalizacja: Będzin
Kontakt:

Post autor: jejek » 20 cze 2008, 13:54

Dużo Ci nie pomogę, bo asembler znam ale dla motoroli 68000, ten intelowy nie był dla mnie strawny. Ale chwała Ci że próbujesz ;)

Z tego co pamiętam, to te rejestry na intelach są każdy do czego innego. Nie każdym możesz zrobić konkretną operację. W odróżnieniu do motorolek czy AVR, gdzie rejestry są uniwersalne (w motoroli nie do końca, ale w uproszczeniu tak).

No więc na tej linii:
  • mov al, [dx]
mam błąd:
  • index register expected
i pokazuje na dx. Jest jakiś rejestr E, który jest jakiś taki do wskazywania obszarów pamięci, jak tam wpisuję el to mi się kompiluje. Czyli zmieniam rejestr i jego wielkość (tak mi się wydaje). Wychodzi że nie można indeksować rejestrem dx (dl też nie, też sprawdzałem).

Kompilowałem na as86 pod linuxem, nie uruchamiałem i na dyskietkę nie wgrywałem, w ogóle to się nie znam ;)
Poczytaj sobie o tych rejestrach, bo ciężko to wymyślić, są tam jakieś połówki tych rejestrów i ta druga litera o tym mówi, al i ah to razem ax czy jakoś tak.

Powodzenia.

Awatar użytkownika
Luminofor
Użytkownik
Posty: 1373
Rejestracja: 27 lis 2007, 17:17
Lokalizacja: Polska

Post autor: Luminofor » 20 cze 2008, 14:04

A może najpierw poćwicz składnię Win32asm i przeczytaj parę kursów asma? A potem idź w 16-bitowe bootsektory. ;)

Awatar użytkownika
jejek
-
Posty: 63
Rejestracja: 12 lip 2005, 8:16
Lokalizacja: Będzin
Kontakt:

Post autor: jejek » 20 cze 2008, 20:44

MichalKaszuba,
Przecież człowiek przerabia kurs i napotkał problem.
Dlaczego akurat Win32asm? Nie znam go ale nie podejrzewam żeby był jakiś wyjątkowy. W asemblerach to już chyba wszystko zostało wymyślone w zeszłym stuleciu. Moim zdaniem jakikolwiek asembler jest dobry. Ja bym polecił inny procesor, ale skoro tak sobie postanowił, to szanuję to.
GrzesiekG,
Ja bym o takie rzeczy pytał na innym forum, programistycznym. To są rzeczy, które ludzie siedzący w temacie od razu Ci objaśnią. Tutaj dostajesz jakieś niepewne informacje :)
P.S. Chyba korzystasz, prawda ? :wink:

Pozdro.

Awatar użytkownika
GrzesiekG
Użytkownik
Posty: 160
Rejestracja: 11 sie 2006, 8:06
Lokalizacja: Annopol
Kontakt:

Post autor: GrzesiekG » 20 cze 2008, 20:54

Drodzy koledzy, nie podejmuję się asm pod windowsem z prostego powodu: potrzebuję napisać programy działające jako OS'y potrzebne do moich "nieco" nietypowych pomysłów (jeśli Bóg da zobaczycie niebawem). Po prostu metoda małych kroczków.
Jeszcze nie popróbowałem Waszych rad bo mam problem z PCem (niebieski ekran po ok. 20min od startu => reinstalka). Jeśli jeszcze ktoś ma jakiś pomysł, proszę zapodać, napewno nie tylko ja skorzystam.

Awatar użytkownika
Luminofor
Użytkownik
Posty: 1373
Rejestracja: 27 lis 2007, 17:17
Lokalizacja: Polska

Post autor: Luminofor » 20 cze 2008, 21:00

Też się kiedyś bawiłem w asma, jednak nie ten level żeby pisał własny OS czy chociaż bootsektor.
Jak asm cię przerasta to spróbuj pisać w C++ ze wstawkami w asm...
Jak robisz bootsector i to bez funkcji, przerwań DOS-owych z tego co pamiętam 21h to musisz zainicjować obsługę ekranu tekstowego (konsola jak w DOS-ie) i chociaż przerwanie klawiatury...
Widzę że obsługę ekranu masz, jeżeli ma tylko wyświetlać to klawiatura nie potrzebna ale przydałoby się jakieś kodowanie znaków ASCII czy coś w tym stylu.
Jak znajdę jakieś tutki to podrzucę.
Powodzenia.

Awatar użytkownika
GrzesiekG
Użytkownik
Posty: 160
Rejestracja: 11 sie 2006, 8:06
Lokalizacja: Annopol
Kontakt:

Post autor: GrzesiekG » 20 cze 2008, 21:58

kodowaniem zajął się kompilator (dlatego zawartość ifo było ujęte w cudzysłów). Co do strachu, nie przerasta mnie asembler, po prostu jeszcze czegoś nie wiem.

elemaniac
Użytkownik
Posty: 585
Rejestracja: 07 maja 2008, 17:09
Lokalizacja: Puławy
Kontakt:

Post autor: elemaniac » 21 cze 2008, 12:57

GrzesiekG, chcesz zrobić własnego OSa?
Możesz skorzystać z gotowego bootloadera np. GRUB, który ładowałby twój system
tak jak tu:
OS Programming - Binboy at Sphere

PS : Chyba nie widziałeś jeszcze tej stronki :mrgreen: .

Awatar użytkownika
GrzesiekG
Użytkownik
Posty: 160
Rejestracja: 11 sie 2006, 8:06
Lokalizacja: Annopol
Kontakt:

Post autor: GrzesiekG » 21 cze 2008, 14:07

Widziałem, korzystałem, dziękuję, ale pragnę przypomnieć: MAM PROBLEM Z KONKRETNĄ INSTRUKCJĄ, nie chcę posklejać urywków z neta, bo nie nauczę się nic. Chcę zrobić od zera i po swojemu (nie ważne jak, byle po swojemu) bootsektor, który mi wypisze na ekranie tekst i się zrestartuje po naciśnięciu klawisza

Awatar użytkownika
jejek
-
Posty: 63
Rejestracja: 12 lip 2005, 8:16
Lokalizacja: Będzin
Kontakt:

Post autor: jejek » 22 cze 2008, 21:36

GrzesiekG, problem masz ze zrozumieniem adresowania w architekturze PC. Tam nie ma bezpośredniego dostępu do całej pamięci. Musisz się odwoływać poprzez tak zwane segmenty. Nie pamiętam jak to się robi dokładnie, ale idea jest taka że ustawiasz sobie segment a dopiero w ramach segmentu odwołujesz się do komórki pamięci. Zawsze mnie przygnębiały te segmenty i nie wdawałem się w szczegóły. Na pewno sobie znajdziesz coś w necie. Słowa kluczowe to adresowanie, segment, x86.
elemaniac, ten artykuł, hmmm, chyba poczytam.

Awatar użytkownika
GrzesiekG
Użytkownik
Posty: 160
Rejestracja: 11 sie 2006, 8:06
Lokalizacja: Annopol
Kontakt:

Post autor: GrzesiekG » 23 cze 2008, 22:15

dziwne:
Bez ingerowania w rejestry segmentowe i miast mov al, [dx] dałem mov al,[info] (czyli wysłanie 1 bajtu do al) to śmiga. A jak dam nawet mov al, [info+dx] to nie balanga (invalid efective adress). Zagłębiłem się w manual do NASM i wynika z tego jasno, że dobrze zrobilem. Czy mam jakoś zmusić kompilatór do posłuszeństwa (próbowałem z byte itp. ale nic nie pomogło)?

[ Dodano: 2008-07-09, 22:45 ]
Ha! Eureka (rzekł Grześ po czym z wrażenia wyskoczył z odzienia) :!:
Genialne rzeczy są proste:

(tutaj bootsektor do pisanego przeze mnie terminala na COM'a):

org 7c00h
start:
xor ax,ax
int 10h

mov cx,2
mov bp, powitanie_text
call pisz

czytaj:
mov ax,8000h
mov es,ax
xor dx,dx
mov bx,dx
mov ax,20h
mov cx,10
int 13h
jc blad

mov cx,83
mov bp,juz_text
call pisz

xor ax,ax
int 16h

jmp 8000h:0000h

blad:
cmp ah,6
jz czytaj
mov cx, 71
mov bp, blad_text
call pisz

xor ax,ax
int 16h
mov bx,40h
mov ds,bx
mov word [ds:72h],1234h

jmp 0FFFFh:0000h

pisz:
push cs
pop es
mov ax,1301h
xor bx,bx
mov bl,0fh
int 10h
ret

powitanie_text db "Laduje PC Terminal v2.0...",13
juz_text db "PC Terminal zaladowany pomyslnie. Nacisnij dowolny klawisz, aby kontynuowac..."
blad_text db "Wystapil blad podczas operacji na dyskietce. Nacisnij dowolny klawisz..."

times 510 -($-start) db 0
dw 0aa55h

Jak można spostrzec wystarczyło zastosowac inne przerwanie a problem sam znika.
Co prawda dalej nie wiem dlaczego występował błąd LEA, chociaż sądzę, że winę tu ponosi kompilator. Poszukam w datasheet'ach Intel'a lub AMD i zapiszę tą instrukcję szesnastkowo i powinno śmigac.
THX FOR ALL HELP.

[ Dodano: 2008-07-10, 08:29 ]
A oto rozwiązanie (cały czas będące na tym kursie, który mi kolega elemaniac polecił):
Używając rejestrów 16-bitowych:
[ (BX albo BP) lub (SI albo DI) lub liczba ]
słowo "albo" wyklucza wystąpienie obu rejestrów na raz
np.

mov al, [ nazwa_zmiennej+2 ]
mov [ di-23 ], cl
mov al, [ bx + si + nazwa_zmiennej+18 ]
bx albo bp lub si albo di <- a nie dx czy jakieś inne cuda.
Ufffffffffff....... Ulga.

ODPOWIEDZ