Project 1: Assembly Language Tips

Tips

Examples

Please read the assembly language provided before reading this section. The file bootblock_examples.s also contains several x86 assembly language examples.

Loading a segment:offset

The project will require you to load a number into a segment register to setup the stack and data segments. The code segment register (CS) cannot be loaded directly, but instead only indirectly through a JMP type instruction. When loading a value into the stack segment register (SS), interrupts are disabled for the next instruction, thus allowing you to set the stack pointer (SP). As an example of setting up the segment registers for data, consider the following string copy:

# Setup the registers - see chapter 3 of Intel ISA reference volume 2
movw DATA_SEGMENT, %ax
movw %ax, %ds
movw OTHER_DATA_SEGMENT, %ax
movw %ax, %es
movw STRING_FROM_ADDRESS, %si
movw STRING_TO_ADDRESS, %di

# Move a byte from one string to the other - implictly DS:SI to ES:DI
movsb

# The values in %si and %di are automatically incremented/decremented based on the DF flag.

Display memory

For your design review you are required to implement routines that print to the screen. During booting, you can write directly to the screen by writing to the display RAM which is mapped starting at 0xb800:0000. Each location on the screen requires two bytes---one to specify the attribute (Use 0x07) and the second for the character itself. The text screen is 80x25 characters. So, to write to i-th row and j-th column, you write the 2 bytes starting at offset ((i-1)*80+(j-1))*2.

So, the following code sequence writes the character 'K' (ascii 0x4b) to the top left corner of the screen.
movw $0xb800,%bx

movw %bx,%es

movw $0x074b,%es:(0x0)

This code sequence is very useful for debugging.


Useful BIOS Features

You are allowed to use these BIOS functions to complete this assignment.

BIOS Int 0x13 Function 2 (From Undocumented PC)

Reads a number of 512 bytes diskette sectors starting from a specified location. The data read is placed into RAM at the location specified by ES:BX. The buffer must be sufficiently large to hold the data AND must not cross a 64K linear address boundary. (For our project, for simplicity, you can assume cylinder number bits 8&9, i.e. bits 6&7 of cl is zero).

Called with:
ah = 2
al = number of sectors to read,
ch = cylinder number, (lowest 8 bits of the 10-bit cylinder number, 0 based)
cl, bits 6&7 = cylinder number bits 8 and 9.
bits 0-5 = starting sector number, 1 to 63

dh = starting head number, 0 to 255
dl = drive number. Use the value of dl that you stored at the beginning of the bootloader.
es:bx = pointer where to place information read from diskette

Returns:
ah = return status (0 if successful)
al = burst error length if ah = 11; undefined on most BIOSes for other ah return status values.
carry = 0 successful, = 1 if error occurred

BIOS Int 0x10 Function 0x0e (From Undocumented PC)

This function sends a character to the display at the current cursor position on the active display page. As necessary, it automatically wraps lines, scrolls and interprets some control characters for specific actions. Note : Linefeed is 0x0a and carriage return is 0x0d

Called with:
ah = 0x0e
al = character to write
bh = active page number (Use 0x00)
bl = foreground color (graphics mode only) (Use 0x02)

Returns:
character displayed