Per scopi didattici, ho adattato questo bootloader da mikeos.berlios.de/write-your-own-os.html riscrivendolo per caricare specificamente all'indirizzo 0x7c00.Come ignorare le chiamate di interruzione durante il debug di un bootloader/bios con gdb e QEMU?
Il codice finale è questo:
[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
posso scorrere il programma e visualizzare i registri cambiando, insieme con l'istruzione in esecuzione, passo con gdb (si) e controllo con monitor QEMU (informazioni registri , x/i $ eip, ecc.).
Dopo essere entrato in int 10h (la routine di stampa del BIOS), le cose si fanno un po 'strane. Se passo istruzioni 500 contemporaneamente, posso vedere il carattere "I" (il primo carattere della mia stringa di testo) stampato sullo schermo. Così ho riavviato di nuovo e fatto un passo di 400 passi (si 400) e poi ho fatto un passo alla volta per vedere in quale fase esatta "I" è stato stampato. Non è mai successo Ho effettivamente fatto 200 passi uno per uno e non è successo nulla. Non appena ho fatto 100 passi alla volta (si 100) ho nuovamente stampato "I" sullo schermo.
Quindi, mi chiedo se c'è un problema di temporizzazione (alcuni interrupt di sistema si intromettono mentre eseguo un debug passo dopo passo). Cos'altro potrebbe essere?
In ogni caso, c'è un modo per saltare l'intero interrupt del BIOS e altre funzioni e tornare indietro e continuare a modificare il codice del bootloader? Come suggerito da Peter Quiring nei commenti, ho provato ad usare il prossimo. Questo non ha funzionato.
(gdb) next
Cannot find bounds of current function
Così ho provato nexti e semplicemente si comporta come si.
Grazie!
Forse l'aggiornamento della schermata qemu funziona in modo diverso se si è single stepping. – Jester
Perché non utilizzare 'next' anziché 'step'ing nell'interrupt? 'next' consentirà l'interruzione per terminare e quindi interrompere l'app sulla linea dopo l'int 10h –
Umm, non è il primo carattere della stringa di testo (come dato) ... 'I'? (non 'F'?), e il secondo char è 't', (non 'I'?) Per quanto riguarda il motivo per cui 500,400,200 ... passaggi nel BIOS danno risultati variabili, non ne ho idea. A meno che non siate curiosi morbosamente, salterò il debug delle routine del BIOS e mi godo il fatto che il vostro settore di avvio funzioni correttamente. Fai attenzione che le chiamate "int 10h" non corrompano il tuo registro "SI", forse un push/pop che circonda "int 10h"? – lornix