Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;This should exist in a new .asm file so that we don't make the boot sector file unreadable
- [bits 16] ;Telling our assembler that this code should be written in 16 bits in case this file get written below some 32 bit code !
- load_disk: ;Reading the disk
- push dx ;Push dx onto the stack
- mov ah, 0x02 ;putting BIOS in reading sector mode
- mov al, dh ;Putting the number of sectors we will be reading in al so that we can check if everything went ok later
- mov ch, 0x0 ;Read cylinder 0 (if we want to be more accurate, we are actually selecting cylinder 0 and reading from there, not reading everything from it)
- mov dh, 0x0 ;Selecting head 0
- nov cl, 0x2 ;Now we actually do the reading. Or we are still selecting, but we choose what to read. We read sector 2 aka the one after our boot sector
- int 0x13 ;BIOS interupt for reading sectors from the disk
- jc disk_error ;Check if any errors happend along the way and go to our disk error managment function to manage it
- pop dx ;Return dx from the stack
- cmp al, dh ;Check if the sectors we read are equal to the sectors we wanted to read
- jne sector_error ;If not, we jump to our sector error managment function
- ret ;Otherwise, we return
- disk_error: ;Disk error managment function
- mov bx, disk_error_message ;Moving our disk error string into bx as an argument for the printing function
- call print_string ;Calling the print string function
- jmp $ ;Hanging in one place, I know this isnt the best way to manage this, but we currently dont have a kernel nor a shell for the user to use to fix or check the error so this is the best we got for now
- sector_error: ;Sector error managment function
- mov bx, sector_error_message ;Moving our sector error string into bx as an argument for the printing function
- call print_string ;Calling our printing function
- jmp $ ;Hanging in one place
- disk_error_message: db 'Something went wrong while reading the disk...OS exiting with code 0xdec1', 0 ;Our disk error string
- sector_error_message: db 'Something went wrong while reading the second sector...OS exiting with code 0xdec2', 0 ;Sector error string
- ;To link this to our boot sector file, we edit the boot sector in the folowing way:
- ;Boot_sector.asm or whatever your is called
- [bits 16] ;Tell nasm that this code should be written in 16 bits !
- [org 0x7c00] ;Tell BIOS where our boot sector should be loaded (the boot sector lays in between the adresses starting from 0x7c00 to 0x7e00)
- mov [BOOT_DRIVE], dl ;BIOS will keep our boot drive in the dl register
- mov bp, 0x9000 ;Place the start of the stack very far away from BIOS files so that we don't overwrite them.
- mov sp, bp ;Same thing here
- mov bx, 0x9000 ;Loading the read sectors to the following memory addreses: from 0x0000, to 0x9000
- mov dh, 5 ;Reading 5 sectors
- mov dl, [BOOT_DRIVE] ;Putting boot drive in dl
- call load_disk ;Calling our disk read function
- mov bx, msg ;Using the register bx as an argument to our print_string function. We put the value of msg in bx
- call print_string ;Call our function for printing strings
- jmp $ ;Jump to the current adress AKA hanging in one place
- %include "{Path to the disk load file}.asm" ;This, when assembled, gets overwritten by all the code in the file we specified, meaning it acts as if it was always written here and not in a different file. !
- BOOT_DRIVE: db 0 ;Asigning out boot drive variable
- print_string: ;Start of our print string function
- pusha ;Push all registers to the stack
- char_loop: ;In this function, we loop through every byte in bx and print it, ending when there are no bytes left
- mov al, [bx] ;Move the next byte into al
- cmp al, 0 ;Check if there is a byte
- jne char_print ;If there is, we print the char
- popa ;If there isn't, we retrieve all registers from the stack
- ret ;And return to our main loop
- char_print: ;Printing individual chars
- mov ah, 0x0e ;Enabling BIOS Tele-type mode
- int 0x10 ;Calling BIOS interupt for printing to screen, equvialent to, in python: 'print(al)'; Interupts are special functions in lower-level programming which when called stop all processes on the pc, do what they must do and let the pc continue it's work
- add bx, 1 ;Moving to the next adress AKA next char in bx
- jmp char_loop ;Going back to the char loop
- msg: db 'Hello world!', 0 ;Making a variable called 'msg' that holds databytes given to it by the db(declare byte(s)). In it's current state it's a char, not a string, so we have to tell the router when to stop printing, which we do witj the ', 0'
- times 510-($-$$) db 0 ;Pad the file with zeros 510 times !
- dw 0xaa55 ;The last two bytes tell BIOS that this is a boot sector and that it should boot it !
- ;All lines that have a '!' at the end of their comments are only read by the assembler and are deleted while assembling.
- ;So lets talk a little bit about what does it mean for our boot sector file to be 512 bytes only. It means that in it, we can only have 512 symbols or bytes. This is problematic, as a boot sector can be more then 512 symbols long, especially if we decide to do extra stuff. The solution to that is to add more space to it by reading the disk and adding some extra memory to our file which should be more then enough for what we need. We will use one of the first addreses that get loaded by our function, which are 0xdada and 0xface, with each being 256 bytes, meaning our boot sector will have a new capacity of 1028 bytes.
- times 256 dw 0xdada ;Adding 0xdada
- times 256 dw 0xface ;And 0xface
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement