This page was last updated on March 13th, 2020(UTC) and it is currently May 30th, 2023(UTC).
That means this page is 3 years, 78 days, 4 hours, 9 minutes and 8 seconds old. Please keep that in mind.

27 - Hello in Bootloader This time you'll want to modify the .S file you created last time so it represents the following:

.intel_syntax noprefix .section .text .code16 start: mov ax, 0xb000 mov ds, ax mov word ptr [0x8000], 0x7032 term: cli hlt jmp term end: .fill (510 - ((end-start) % 512)), 1, 0 .byte 0x55 .byte 0xaa

Now, to run the thing, to show what is going on, you need to compile and run this thing. Once again, invoking AS "as -o main.o main.S" to get the object file. This time, we're going to use LD manually to get the output. "ld -Ttext 0x7c00 main.o --oformat=binary" where "ld" is the linker, "-Ttext 0x7c00" means we want the code's jmp family of instructions to have 0x7c00 added to them, since that's where the BIOS is going to load the binary. Next, run "boot a.out" and "2" should appear on the bottom of the screen.

So let's digest what's happening: ".intel_syntax noprefix" meands we want to use intel syntax. ".section .text" is the same it has always been. "start:" is a label, which we use to represent values that we don't want to manutally type in, which, since it is the type ending with a colon, the value represents the location in ram of the next instruction. Next we have "mov ax, 0xb000" to make the "ax register" contain 0xb000 (I'll elaborate on the registers for x86 later). "mov ds, ax" means we're putting the value of "ax" into the "ds register" (for data segments), which is important 'cause we don't know what value it could have by default, and it can affect interpretation of where data is. Next we're moving 0x32 into 0xb8000 (segment registers are multiplied by 16 and then added to whatever pointer is being used), then clearing the interrupt flag (to disable hardware interrupts which would call other interrupt routines), using "hlt" to tell the computer to, essentially, freeze, then we're jumping back to the CLI instruction. From there, i have an expression that tries to fill (you should be looking at a manual for gnu AS directives for more information) the file so that it's filled with 0xCC (which is the int3 instruction, which is good practice whenever you want to fill a large area of executable space), and then a "word" (2 bytes on x86" with the value of 0xaa55, which is expected by some standard to be at the end of a bootloader (at 0x7e00, or 512 bytes after the beginning). If you were to write this at location 0 of a floppy disk, throw it into a comptuer that has a floppy drive, and make the BIOS "boot from floppy drive," you would see this working on a real computer (good luck on your museum robbing adventures).

Now, for some of you, this might not actually happen, because your DOS emulator doesn't have "boot" or maybe DOSBox cut support for "boot." The objective here was to give you a program that you could, at least in theory, run without relying on DOS. OS development can be entertaining as an exercise, but it's not very practical in a DOS emulator. From now on, we're going to have to rely on GCC to make an MZ (DOS executable) file for us in the right format, and we're going to be using clib and maybe a few more interrupts. I just felt it important for you to get a taste for the real world that hides behind all the abstraction, so you're not afraid to get into microcontroller assembly and the like. At the end of the day, linkers and such are for convenience, not to really reduce difficulty like some would suggest.

Get your own web kitty here!
©Copyright 2010-2023. All rights reserved.