Как использовать более 512 байт моей загрузочной дискеты
Я изучаю ассемблер, я выполнил http://mikeos.berlios.de/write-your-own-os.html шаги для создания загрузочной графической игры, но у меня есть проблема: я не могу использовать больше 512 байт памяти для моей программы.
Как я могу решить эту проблему?
Я ценю любую помощь.
Вот мой код (все еще меньше чем 512 байтов): http://pastebin.com/i6ehx8dT
Редактировать: я решаю свою проблему, вот минимальный пример загрузчика гибких дисков, сделанный на ассемблере 16 бит: http://pastebin.com/x1SawyjN
Наконец, эта ссылка была очень полезной: http://www.nondot.org/sabre/os/files/Booting/nasmBoot.txt
2 ответа
Это не легко сделать:
На самом деле BIOS загружает в память только первые 512 байт диска.
Затем вам нужно загрузить остальные данные в память. Обычно это делается с использованием прерывания 13h (подфункции AH=2 или AH=42h).
Если вы точно знаете, где на диске находятся данные, это довольно просто. По этой причине загрузчики, такие как GRUB, используют общеизвестные места - к сожалению, такие места иногда перезаписываются другими программами, такими как драйверы защиты от копирования.
Если вам нужно загрузить из четко определенной файловой системы (например, FAT или NTFS), это более сложно: у вас есть только ~450 байтов пространства (потому что ~60 из 512 байтов используются файловой системой внутри) для кода, который интерпретирует данные файловой системы, находит файл, содержащий код, и загружает его в память!
Вот простой загрузчик, который я сделал:
[org 0x7c00]
; stack and segment setup
xor ax, ax
mov es, ax
mov ds, ax
mov bp, 0x1200 ; thank you user ecm for notifying me to not use
; 0x8000 as the stack address
mov ss, ax ; thank you user ecm for notifying me to add this specified line of code
mov sp, bp
; load more than 512 bytes into memory
mov ah, 0x02 ; read sectors
mov al, 0x01 ; sectors to read
mov ch, 0x00 ; cylinder idx
mov dh, 0x00 ; head idx
mov cl, 0x02 ; sector idx
mov dl, 0x00 ; disk idx
mov bx, program ; address of more than 512 bytes
int 0x13
; because i'm tired you can do the error checking by checking if al is the
; same as what you set it to and checking for the carry flag
; jump to program (no error checking!)
jmp program
times 510-($-$$) db 0
dw 0xAA55
; more than 512 bytes program
program:
mov ah, 0x0E
mov bh, 0x00
mov al, 'A'
int 0x10
jmp $
; amount of zeros = 512 + (number of sectors read * 512)
times 1024-($-$$) db 0