W celach edukacyjnych zaadaptowałem ten program ładujący z mikeos.berlios.de/write-your-own-os.html, przepisując go tak, aby ładował się pod adresem 0x7c00.Jak przerwać przerywanie wywołań podczas debugowania bootloadera/biosu za pomocą gdb i QEMU?
Ostateczny kod jest taka:
[BITS 16] ; Tells nasm to build 16 bits code
[ORG 0x7C00] ; The address the code will start
start:
mov ax, 0 ; Reserves 4Kbytes after the bootloader
add ax, 288 ; (4096 + 512)/ 16 bytes per paragraph
mov ss, ax
mov sp, 4096
mov ax, 0 ; Sets the data segment
mov ds, ax
mov si, texto ; Sets the text position
call imprime ; Calls the printing routine
jmp $ ; Infinite loop
texto db 'It works! :-D', 0
imprime: ; Prints the text on screen
mov ah, 0Eh ; int 10h - printing function
.repeat:
lodsb ; Grabs one char
cmp al, 0
je .done ; If char is zero, ends
int 10h ; Else prints char
jmp .repeat
.done:
ret
times 510-($-$$) db 0 ; Fills the remaining boot sector with 0s
dw 0xAA55 ; Standard boot signature
mogę przejść przez program i zobaczyć rejestry zmienia, wraz z instrukcją aktualnie wykonywany, wychodząc z gdb (SI) i inspekcji z QEMU monitor (Informacje rejestry , x/i $ eip, itp.).
Po tym, jak dostaję się do 10h (procedura drukowania BIOS), sprawy stają się trochę dziwne. Jeśli zrobię krok 500 instrukcji naraz, na ekranie pojawi się znak "I" (pierwszy znak z mojego ciągu tekstowego). Ponownie uruchomiłem ponownie i wprowadziłem 400 kroków (si 400), a następnie zrobiłem krok po kroku, aby zobaczyć, w którym dokładnie kroku "I" został wydrukowany. To nigdy się nie stało. Właściwie zrobiłem 200 kroków jeden po drugim i nic się nie stało. Jak tylko podniosłem 100 kroków naraz (si 100), znowu "I" wydrukowałem na ekranie.
Zastanawiam się, czy istnieje problem z synchronizacją (niektóre zakłócenia systemowe stają na przeszkodzie podczas wykonywania krok po kroku debugowania). Cóż innego mogłoby to być?
Czy istnieje sposób na pominięcie całego przerwania BIOS i innych funkcji i po prostu wróć i kontynuuj wprowadzanie kodu bootloadera? Jak zasugerował Peter Quiring w komentarzach, spróbowałem użyć next. To nie zadziałało.
(gdb) next
Cannot find bounds of current function
Więc spróbowałem nexti i po prostu zachowuje się jak si.
Dzięki!
Może aktualizacja ekranu qemu działa inaczej, jeśli wykonujesz pojedyncze czynności. – Jester
Dlaczego nie używać "następnego" zamiast "stepować" do przerwania? "Dalej" pozwoli przerwać, aby zakończyć, a następnie zatrzymać aplikację na linii po int 10h –
Umm, nie jest pierwszym znakiem ciągu tekstowego (jak podano) ... "ja"? (nie "F"?), a drugi znak to "t", (nie "I"?) Dlaczego 500 40000 ... kroków do BIOS daje różne wyniki, nie mam pojęcia. Jeśli nie jesteście chorobliwie ciekawi, pominęłbym debugowanie procedur BIOS i cieszę się, że twój sektor rozruchowy działa poprawnie. Uważaj, że wywołania 'int 10h' nie psują twojego rejestru' SI', być może push/pop otaczającego 'int 10h'? – lornix