19 November 2003 (Revised 21 November 2003) Boot sector The boot sector is the first sector (512-byte chunk of space) on a disk. When you reboot your computer with a floppy disk in the drive, the computer loads the boot sector and runs the code found there. My boot-sector code here has only the most basic functionality: It sets up the stack and the segment registers to ensure that code can function properly in real mode, and it calls a BIOS routine to print something to the screen so that you can see that it worked. This code works with NASM. You might have to fiddle with it to make it work with other assemblers. The code starts at absolute address 0x7C00, and it is real-mode (16-bit) code. [ORG 0x7C00] [BITS 16] The first thing I do is set the current code segment to zero — it might be something else. The address of the boot sector can be expressed in real mode as any of a number of segment:offset pairs. The address could be 0:0x7C00, or 0x07C0:0, or something else. If the address is 0:0x7C00, then the processor can call code anywhere in the bottom 64KB of memory (0:0x0000 to 0:0xFFFF) without using far calls or segment overrides. If the address is 0x07C0:0, then the memory in the code segment begins at the start of the boot sector, and we can't call code below that point without a far call or a segment override. I want to reserve the bottom 64KB for real-mode code and data — Karig might use the real-mode BIOS services for loading data from and saving it to disk — so I want the code segment to be zero. The accepted way to change the code segment is with a far jump — in this case, to the next instruction. jmp word 0:segzero segzero: Then I set all of the data-segment registers to the same segment as CS. mov ax, cs mov ds, ax mov es, ax mov fs, ax mov gs, ax Then I set up a return stack. I decided to put the stack in a different segment — namely, in the second 64KB chunk of memory (segment 0x1000). (Always disable interrupts whenever setting up a stack! An interrupt can happen at any time, and it needs to put things onto the stack!) cli mov ax, 0x1000 mov ss, ax mov sp, 0xFFFE sti Now I verify that the boot sector loaded and that the stack is OK by calling a BIOS routine to print characters to the screen. Specifically, I use interrupt 0x10, function 9 to print "YYYYYYYY" on the screen in black letters on a green background. mov al, 'Y' xor bh, bh mov bl, 0x20 mov cx, 8 mov ah, 9 int 0x10 Finally, I need to halt the computer so that the CPU doesn't try executing random data in memory — such as something that causes the computer to reboot. I want to be sure that I can see the result on the screen after the code finishes executing. jmp $ To ensure that the BIOS will recognize this chunk of code as a boot sector, we have to ensure that it is 512 bytes long, and that the last two bytes are 0x55 and 0xAA. times 510 - ($-$$) db 0 db 0x55, 0xAA Other pages on writing a boot sector
If you didn't find this page helpful, here are more pages (and ZIP files) for you to explore.
• The Boot Sector Check the index for other entries. |