For one of my projects, I'm learning a bit of x86 assembly.
Some initial goals were:
- Print a string of text on the screen
- Be able to use all 16 colours
- Position the text cursor
- Do NOT use BIOS interrupts (because it may eventually have to run in protected mode)
I came up with this:
%define CODE_BASE 0x07C0 ;; 'UselessOS 1.2' a.k.a. 'Print some coloured text, position a cursor and quit' ;; Created: 2011-05-06/2011-05-07 ;; By: Marcel van den Boer ;; ;; Released in the PUBLIC DOMAIN ;; ;; Build and run with: ;; $ nasm -f bin -o colortext.bin colortext.asm ;; $ dd if=/dev/zero of=colortext.img bs=2880 count=512 ;; $ dd status=noxfer conv=notrunc if=colortext.bin of=colortext.img ;; $ qemu -fda colortext.img ;; ;; Resources: ;; - http://mikeos.berlios.de/write-your-own-os.html ;; - http://www.jamesmolloy.co.uk/tutorial_html/ ;; - http://wiki.osdev.org/Memory_Map_%28x86%29 ;; - http://www.tarleton.edu/computerscience/documents/CS%20380/ ... ;; ... Labs/Lab%203%20-%20Kernel.pdf ; Color definitions %define BLACK 0x0 %define BLUE 0x1 %define GREEN 0x2 %define CYAN 0x3 %define RED 0x4 %define MAGENTA 0x5 %define YELLOW 0x6 %define WHITE 0x7 ; Color brightness %define NORMAL 0x0 %define BRIGHT 0x8 ; Video memory facts %define COLOR (BACKGROUND << 4 | FOREGROUND) %define CURSOR ((CURSOR_Y * COLUMNS) + CURSOR_X) %define VIDEO_BASE 0xB800 %define COLUMNS 80 %define ROWS 25 ; Text to print %define MESSAGE 'Useless OS 1.2 loaded... Goodbye!' %define FOREGROUND (YELLOW | BRIGHT) %define BACKGROUND (BLUE | BRIGHT) ; Where to place the cursor %define CURSOR_X 79 %define CURSOR_Y 24 init: ; Note: This section marked 'init' is not required for the remaining code ; It's just here for my own reference cli ; Set up stack mov ax, 0x07E0 mov ss, ax mov esp, (0x0007FFFF - 0x00007E00) cursor: ; Lower byte mov byte al, 0x0F mov word dx, 0x03D4 out dx, al mov byte al, CURSOR mov word dx, 0x03D5 out dx, al ; Upper byte mov byte al, 0x0E mov word dx, 0x03D4 out dx, al mov byte al, CURSOR >> 8 mov word dx, 0x03D5 out dx, al start: ; Initialize registers which will be modified later (pointers) mov word si, 0 mov word di, MSG_BASE ; Initialze registers with non-changing data mov word ax, CODE_BASE mov word bx, VIDEO_BASE ; Set character color mov byte ch, COLOR fetch: ; Fetches the next character mov word ds, ax ; Align with code mov byte cl, [di] ; Fetch character inc di ; Increment character index print: ; Prints the most recently loaded character mov word ds, bx ; Align with video memory mov word [si], cx ; Print character add si, 2 ; Increment video index branch: ; Fetch the next character if the end of the string has not been reached cmp cl, 0 jne fetch ; Otherwise fill the screen with the last (null) character cmp si, (COLUMNS * ROWS * 2) jl print end: ; Finally, wait forever jmp $ data: MSG_BASE db MESSAGE, 0 padding: ; Required to be recognized as a boot sector times 510-($-$$) db 0 dw 0xAA55
(It is has version number 1.2 because: "1.0" printed the string and cleared the screen, "1.1" added colour and "1.2" added cursor management. Though every version was made in the last two days.)
Enjoy.
No comments:
Post a Comment