This program demonstrates how EuroAssembler creates executable programs in the format BOOT.
Boot sector is a 512 bytes long image recorded in the first sector of disk volume. When personal computer starts, its BIOS will read boot sector and store its contents at address 0x07C00 in memory.
Code in this sector is executed in real CPU mode, no DOS services are available yet. Since the binary format cannot contain any metainformation (entry point, relocations etc), all absolute addresses in its code must be assembled to fixed values.
BIOS loads the sector at agreed linear address 0x07C00 and then it will set register DL to the drive number (DL=0 for floppy drive A:), CS=0x0000 and IP=0x7C00 (some BIOS vendors may prefer CS=0x07C0 and IP=0x0000). Other registers are undefined. This transfers control to the first boot-sector instruction at CS:0x7C00.
When loaded on real PC (not on simulator/virtual PC), BIOS may overwrite some bytes near the beginning with disk parameters, that's why its safer to reserve 60 bytes for OEM_ID, BPB, DPT.
This boottest.sec
doesn't boot anything, it just displays some text as it's used for demonstration only.
EuroAssembler pseudoinstruction PROGRAM FORMAT=BOOT
implies properties of the output file:
.sec
boottest.secto the first disk sector, for instance
dd.exe if=boottest.sec of=\\.\A:
(Windows) or dd if=boottest.sec of=/dev/fd0
(Linux) and then boot from the disk A:.EUROASM ; Use default EuroAssembler options. boottest PROGRAM Format=BOOT ; Use default program options for the format BOOT (WIDTH=16,MODEL=TINY). JMPS Start: times %FOR 1..60 ; Reserve 60 bytes of NOP for BIOS. NOP %ENDFOR times Start: CLI ; Disable HW interrupts, as the stack is not settled yet. SUB AX,AX MOV DS,AX ; Initialize DS to 0 because boot image is linked at offset 0x7C00. MOV SS,AX MOV SP,0FFFEh ; Position the top of stack just below our bootsector code. STI .Again: MOV SI,=B "Hello, world!" CALL WriteLn.B16: MOV SI,=W 0007h ; Let DS:SI point to a character 07h (BEL), zero-terminated. CALL WriteLn.B16 ; Use BIOS to ring a bell (to beep). MOV SI,=B "Boot sector created by EuroAssembler was loaded and executed succesfully." CALL WriteLn.B16: MOV SI,=B "Press any key to repeat." CALL WriteLn.B16: SUB AX,AX ; BIOS INT 16h function GET KEYSTROKE. INT 16h ; Wait for the keystroke. JMP .Again: ;; WriteLn.B16:PROC ; Display a line of ASCIIZ string DS:SI using BIOS. Clobbers AX,BX,SI. CLD ; Load the string forward. MOV AH,0Eh ; BIOS INT 10h function TELETYPE OUTPUT. MOV BX,0007h ; Videopage 0, default colour (white on black). .NextChar:LODSB ; Let AL=[DS:SI], increment SI. TEST AL ; Test if it's end of the string. JZ .LineFeed: ; Continue with CR+LF in the end, INT 10h ; otherwise display the nonzero character in AL JMP .NextChar: ; and continue with the next character. .LineFeed:MOV AL,0Dh ; Carriage Return. INT 10h ; Return the cursor left. MOV AL,0Ah ; Line Feed. INT 10h ; Move the cursor one line down, scroll if necessary. RET ENDPROC WriteLn.B16 ENDPROGRAM boottest ; Program format BOOT will append signature 0x55,0xAA at the end of sector.