Czytając kurs ze strony: http://www.osprogramming.webpark.pl/part2.html
Zrobiłem jak tam pisało i... nie działa :( Co zrobiłem źle?
Kod:
boot.asm
[ORG 0h]
jmp 07C0h:start
msg DB 'Witaj w boot sektorze.', 13, 10, 0
start:
mov ax, 07C0h
cli ; przed ustawianiem stosu w celach
; bezpieczeństwa powinno się wyłączyć przerwania
mov ss, ax ; ustawiamy segment stosu
mov sp, 03FEh ; i wskaźnik pokazujący na szczyt stosu
sti ; włączamy przerwania
push cs
pop ds
pop es ; odrazu wykorzystamy stos iniciując nasze rejestry segmentowe
;funkcyjka wyswietlajaca napis(w niezbyt dobrym stylu)
mov si, msg
next_char:
mov al, [si]
cmp al, 0
jz char_end
inc si
mov ah, 0eh
int 10h
jmp next_char
char_end:
mov ah, 02h ; odczytaj sektor z dyskietki
mov al, 1 ; ile sektorow
mov ch, 0 ; numer sciezki
mov cl, 2 ; numer sektora
mov dh, 0 ; glowica
mov dl, 0 ; numer dysku
mov bx, 0800h
mov es, bx
mov bx, 0 ; odczytany sektor zapisujemy pod adresem 0800:0000h
int 13h ; i z tak przygotowanymi danymi wywolujemy przerwanie
jmp 0800h:0000h ; skok do kernela ktory przed chwila wczytalismy z dyskietki
times 510-($-$$) db 0 ; uzupelnienie pliku tak aby zawieral 510 bajtow
dw 0xAA55 ; sygnaturka (2 bajty), plik ma razem 512 bajtow (200h)
kernel.asm
[org 0x0000]
[bits 16]
[SEGMENT .text]
get_cmd:
mov BYTE [CmdSize],0 ; zerujemy zmienną przechowującą
; bieżącą liczbę znaków w buforze
mov di, UserCmd ; wpisujemy do DI offset bufora na komende
get_cmd_start:
mov ah,10h
int 16h ; pobieramy znak z klawiatury
cmp al,0 ; al=0 gdy wciśnięty klawisz to klawisz rozszerzony
je get_cmd_start ; jeżeli tak to wróć do początku,
; jeżeli nie to przejdz dalej
cmp al,08h ; sprawdź czy wciśnieto spację
je backspace_key ; jeżeli tak to skocz do podprocedury obsługującej spację
cmp al,0dh ; sprawdź czy wciśnięty klawisz to enter
; (czyli koniec polecenia)
je enter_key ; jeżeli tak to skocz do odpowiedniego miejsca
; pobrany znak to zwykły znak ascii
mov bh, [MaxLen]
mov bl, [CmdSize]
cmp bl, bh ; sprawdz czy nie osiągnięto max dozwolonej ilości znaków
je get_cmd_start ; jeżeli tak to wróć do początku
space:
mov ah, 0Eh
mov al, 20h ; kod ascii spacji
mov bh, 00h ; strona graficzna
mov bl, 07h ; atrybuty tekstu
int 10h ; wywołanie przerwania
ret
next_line:
mov ah, 0Eh
mov al, 0Dh
mov bh, 00h
mov bl, 07h
int 10h
mov ah, 0Eh
mov al, 0Ah
mov bh, 00h
mov bl, 07h
int 10h
ret
prompt:
mov ah, 0Eh
mov al, 02h
mov bh, 00h
mov bl, 07h
int 10h
ret
backspace_key: ; jeżeli wciśnięto backspace...
mov bl,0
mov bh,[CmdSize]
cmp bh,bl ; jeżeli w buforze nie ma nic, to znaczy,
je get_cmd_start ; że nia ma czego usuwać, wróć więc do początku
; usuwamy ostatni znak i z bufora i z ekranu
dec BYTE [CmdSize] ; zmniejsz licznik wpisanych znakow
dec di ; zmniejsz bufor
mov ah, 0Eh ; przesuń kursor w lewo wypisując backspace
int 10h
mov ah, 09h ; wyczyść znak pod kursorem nie przesuwając go
mov al, ' '
mov bh, 0h
mov bl, 07h
mov cx, 1
int 10h
jmp get_cmd_start ; wróć do początku
enter_key: ; jeżeli wciśnieto enter to dopisz 0
mov BYTE [di], 0x00 ; na koniec bufora i wyjdź
ret
reboot:
jmp 0FFFFh:0000h
; nie musimy dodawać instrukcji ret gdyż z tej funkcji nie wracamy
clear_screen:
push ax
push ds
push bx
push cx
push di
mov AX, 40h
mov DS, AX
mov AH, 06h
mov AL, 0
mov BH, 07
mov CH, 0
mov CL, 0
mov DI, 84h
mov DH, [DI]
mov DI, 4Ah
mov DL, [DI]
dec DL
int 10h
mov BH, 0
mov DL, 0
mov DH, 0
mov AH, 02
int 10h
pop di
pop cx
pop bx
pop ds
pop ax
ret
version:
mov si,OsName
call disp_str
mov si,MajorVer
call disp_str
mov si,MinorVer
call disp_str
ret
help:
mov si,msgHelp
call disp_str
ret
execute:
mov si, UserCmd
cmp BYTE [si], 0h
je koniec_execute ; jeżeli bufor polecenia jest pusty nie wykonujemy żadnej akcji
cmd_ver: ; sprawdzamy czy pobrane polecenie to nie 'version'
mov si, UserCmd
mov di, cmdVersion
mov cx, 8
repe cmpsb
jne cmd_reset ; jeżeli nie to sprawdzamy nastepnš mozliwość
call version ; jeżeli tak to skaczemy do odpowiedniej funkcji
jmp koniec_execute ; i wracamy do pętli glownej
cmd_reset:
mov si, UserCmd
mov di, cmdReboot
mov cx, 7
repe cmpsb
jne cmd_clrscr
call reboot
cmd_clrscr:
mov si, UserCmd
mov di, cmdClrscr
mov cx, 7
repe cmpsb
jne cmd_help
call clear_screen
jmp koniec_execute
cmd_help:
mov si, UserCmd
mov di, cmdHelp
mov cx, 5
repe cmpsb
jne UnknownCmd
call help
jmp koniec_execute
UnknownCmd:
mov si,cmdUnknown
call disp_str
koniec_execute:
ret
disp_str:
lodsb ; load next character
cmp al, 0 ; sprawdza czy nie 0
je .DONE ; jeżeli tak to kończy
mov ah, 0x0E
int 10h
jmp disp_str
.DONE:
ret
[SEGMENT .data]
MaxLen db 40h ; maksymalna długość polecenia - 64 znaki
OsName db 13,10,"LukOS RMODE",13,10,0
MajorVer db "Wersja 1",0
MinorVer db ".02",0
msgHelp db 13,10,"Dostepne polecenia:",13,10,
db "clrscr - czysci ekran",13,10,
db "help - wyswietla liste dostepnych polecen",13,10,
db "version - wyswietla nazwe i wersje systemu",13,10,
db "reboot - restartuje komputer",0
cmdVersion db "version",0
cmdReboot db "reboot",0
cmdClrscr db "clrscr",0
cmdHelp db "help",0
cmdUnknown db 13,10,"Nieznane polecenie! Wpisz 'help', aby uzyskac pomoc",0
[SEGMENT .bss]
UserCmd resb 40h ; tekst wpisany przez użytkownika
CmdSize resb 0 ; ilość wpisanych znaków
Potem traktuje to merge Wolverina i wczytuje obraz do VirtualBox i wyświetla się tylko napis Witaj w boot sektorze. Dalej nic :(