These are notes made while disassembling the Windows XP Service Pack 3 bootsector (x86 real mode) code.
; File Name : C:\Users\anonymous\Documents\windows_xpsp3_bootsector.img
; Format : Binary file
; Base Address: 0000h Range: 0000h - 0200h Loaded length: 0200h
.686p
.mmx
.model flat
; ===========================================================================
; Segment type: Pure code
seg000 segment byte public 'CODE' use16
assume cs:seg000
assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
; =============== S U B R O U T I N E =======================================
; ORIGin is 0x7C00
sub_0 proc far
xor ax, ax ; AX = 0
mov ss, ax ; SS = 0
mov sp, 7C00h ; SP = 0x7C00
sti ; enable interrupts
push ax ; *SP = 0
pop es ; ES = *SP
push ax ; *SP = 0
pop ds ; DS = *SP
cld ; clear direction (left to right)
mov si, 7C1Bh ; for (int i = 0; i < 0x1E5; i++)
; *((BYTE* ) 0x061B) = *((BYTE* ) &0x7C1B);
mov di, 61Bh
push ax ; puts value of zero on top of stack
push di ; *SP = 0x061B
mov cx, 1E5h ; CX = 0x1E5 (number of elements to copy)
rep movsb ; copy byte by byte
retf ; 0000:061B
sub_0 endp
; =============== S U B R O U T I N E =======================================
; THIS CODE IS COPIED TO 0x061B FOR 0x1E5 BYTES (see above)
; This area is 0000:061B to 0000:0800 in RAM
sub_1B proc far
mov bp, 7BEh ; BP points to partition table
mov cl, 4 ; sets counter to 4 (max number active partitions)
; loc_20 is _FindActivePartition
loc_20: ; CODE XREF: sub_1B+Fj
cmp [bp+0], ch ; *(BP + 0) = 0x80 (drive number)
jl short loc_2E ; jumps ((signed int)(0x0 - 0x80) < 0)
jnz short loc_3A ; jump if Active flag was negative (0xF0 to 0xFF, inclusive)
add bp, 10h ; only gets here if Active flag was zero (0x00)
loop loc_20 ; loop a maximum of four times, trying to find active partition
; reboot/pause if active partition not found after four attempts
int 18h ; TRANSFER TO ROM BASIC
; causes transfer to ROM-based BASIC (IBM-PC)
; often reboots a compatible; often has no effect at all
; loc_2E is _SuccessFoundActivePartition
loc_2E: ; CODE XREF: sub_1B+8j
mov si, bp ; if we made it here, we found the partition
loc_30: ; CODE XREF: sub_1B+1Dj
add si, 10h ; point to next partition entry
dec cx ; decrease counter
jz short loc_4F; jump if parsed all four partition table entries
cmp [si], ch ; check to see if active flag in next entry is NULL
jz short loc_30; check next partition entry, if we have any left (four possible)
; loc_3A is _PrintInvalidPartitionTable
loc_3A: ; CODE XREF: sub_1B+Aj
mov al, ds:7B5h ; AL = *(0x07B5) [2C]
loc_3D: ; CODE XREF: sub_1B+4Ej sub_1B+64j ...
mov ah, 7 ; AH = 0x07
mov si, ax ; DATA XREF: sub_1B+30r (0x072C)
; 0x072C = "Invalid partition table"
; loc_41 is _LoadNextErrorChar
loc_41: ; CODE XREF: sub_1B+32j
lodsb ; load character at ((BYTE* ) 0x072C++)
; loc_42 is _PrintErrorThenInfiniteLoop
loc_42: ; CODE XREF: sub_1B+29j
cmp al, 0 ; until the byte is NULL (infinite loop!)
jz short loc_42
mov bx, 7 ; BX = 0x7
mov ah, 0Eh ; AH = 0xE
int 10h ; DATA XREF: sub_9B+8r sub_9B+3Br ...
; - VIDEO - WRITE CHARACTER AND ADVANCE CURSOR (TTY WRITE)
; AL = character, BH = display page (alpha modes)
; BL = foreground color (graphics modes)
jmp short loc_41; load next character
; ---------------------------------------------------------------------------
; loc_4F is _PartitionTableParsed
loc_4F: ; CODE XREF: sub_1B+19j
mov [bp+10h], cl; set next partition entry to inactive (why?)
call sub_9B
jnb short loc_81
loc_57: ; CODE XREF: sub_1B+72j
inc byte ptr [bp+10h]
cmp byte ptr [bp+4], 0Bh
jz short loc_6B
loc_60: ; DATA XREF: sub_1B+11r
cmp byte ptr [bp+4], 0Ch
jz short loc_6B
mov al, ds:7B6h
jnz short loc_3D
loc_6B: ; CODE XREF: sub_1B+43j sub_1B+49j
add byte ptr [bp+2], 6
add word ptr [bp+8], 6
adc word ptr [bp+0Ah], 0
call sub_9B
jnb short loc_81
mov al, ds:7B6h
jmp short loc_3D
; ---------------------------------------------------------------------------
; loc_81 is _CheckPartitionMagic
loc_81: ; CODE XREF: sub_1B+3Aj sub_1B+5Fj
cmp word ptr ds:7DFEh, 0AA55h
jz short loc_94
cmp byte ptr [bp+10h], 0
jz short loc_57
mov al, ds:7B7h
jmp short loc_3D
; ---------------------------------------------------------------------------
; loc_94 is _LegitimatePartitionMagic
loc_94: ; CODE XREF: sub_1B+6Cj
mov di, sp ; DI = 0x7C00
push ds ; *(SP) = 0
push di ; *(SP) = 0x7C00
mov si, bp ; SI = 0x07BE (pointer to partition table entry)
retf ; returns to 0000:7C00
; END OF CURRENT ANALYSIS
; GO TO PART 2 !!!!!!!!!!!!!!!!
; GO TO PART 2 !!!!!!!!!!!!!!!!
; GO TO PART 2 !!!!!!!!!!!!!!!!
sub_1B endp ; sp-analysis failed
; =============== S U B R O U T I N E =======================================
sub_9B proc near ; CODE XREF: sub_1B+37p sub_1B+5Cp
mov di, 5 ; DI = 5 (write drive parameter to 0000:0005)
mov dl, [bp+0] ; DL = drive number (0x80)
mov ah, 8
int 13h ; DISK - DISK - GET CURRENT DRIVE PARAMETERS (XT,AT,XT286,CONV,PS)
; DL = drive number (0x80)
; Return: CF set on error, AH = status code (0x8), BL = drive type (0)
; DL = number of consecutive drives (0x1)
; DH = maximum value for head number (0xFE), ES:DI -> drive parameter (0000:0005)
; 0000:0005 points to Disk Base Table (http://stanislavs.org/helppc/dbt.html)
; value is : 0xFF 0x00 0xF0 0x53 0xFF 0x00 0xF0 0x53 0xFF 0x00 0xF0
; returns CF = 0
jb short loc_CA ; jumps if failed
mov al, cl ; AL = 0xBF
and al, 3Fh ; AL = 0x3F (why?)
cbw ; AX = 0x003F
mov bl, dh ; BL = 0xFE
mov bh, ah ; BH = 0
inc bx ; BX = 0x00FF
mul bx ; 0xFF * 0x3F = 0x3EC1
; AX = 0x3EC1
mov dx, cx ; DX = 0x09BF
xchg dl, dh ; DL = 0x09
; DH = 0xBF
mov cl, 6 ; CX = 0x0906
shr dh, cl ; DX = 0x0209
inc dx ; DX = 0x020A
mul dx ; 0x020A * 0x3EC1 = 0x7FF58A (Logical Block Addressing)
; DX = 0x7F
; AX = 0xF58A
cmp [bp+0Ah], dx ; 0 < 0x7F
ja short loc_E6 ; definitely not
jb short loc_CA ; yes
cmp [bp+8], ax ; 0x003F < 0xF58A (doesn't get here normally)
jnb short loc_E6 ; jumps if something is messed up? has to check for INT 13 extensions
; loc_CA is _GetCurrentDriveParametersError
loc_CA: ; CODE XREF: sub_9B+Aj sub_9B+28j ...
mov ax, 201h ; AX = 0x0201
mov bx, 7C00h ; BX = 0x7C00
mov cx, [bp+2] ; CX = 0x00 (track) 01 (sector)
mov dx, [bp+0] ; DX = 0x01 (head) 80 (drive)
int 13h ; DISK - READ SECTORS INTO MEMORY
; AL = number of sectors to read, CH = track, CL = sector
; DH = head, DL = drive, ES:BX -> buffer to fill (0000:7C00)
; Return: CF set on error, AH = status, AL = number of sectors read
; Returns CF = 0
jnb short locret_12B ; jumps on successful read (ours)
dec di
jz short locret_12B
xor ah, ah
mov dl, [bp+0]
int 13h ; DISK - RESET DISK SYSTEM
; DL = drive (if bit 7 is set both hard disks and floppy disks reset)
jmp short loc_CA
; ---------------------------------------------------------------------------
loc_E6: ; CODE XREF: sub_9B+26j sub_9B+2Dj
mov dl, [bp+0]
pusha
mov bx, 55AAh
mov ah, 41h ; 'A'
int 13h ; DISK - Check for INT 13h Extensions
; BX = 55AAh, DL = drive number
; Return: CF set if not supported
; AH = extensions version
; BX = AA55h
; CX = Interface support bit map
jb short loc_129
cmp bx, 0AA55h
jnz short loc_129
test cl, 1
jz short loc_129
popa
loc_FF: ; CODE XREF: sub_9B+8Cj
pusha
push 0
push 0
push word ptr [bp+0Ah]
push word ptr [bp+8]
push 0
push 7C00h
push 1
push 10h
mov ah, 42h ; 'B'
mov si, sp
int 13h ; DISK - IBM/MS Extension - EXTENDED READ (DL - drive, DS:SI - disk address packet)
popa
popa
jnb short locret_12B
dec di
jz short locret_12B
xor ah, ah
mov dl, [bp+0]
int 13h ; DISK - RESET DISK SYSTEM
; DL = drive (if bit 7 is set both hard disks and floppy disks reset)
jmp short loc_FF
; ---------------------------------------------------------------------------
loc_129: ; CODE XREF: sub_9B+56j sub_9B+5Cj ...
popa
stc
locret_12B: ; CODE XREF: sub_9B+3Dj sub_9B+40j ...
retn ; returns to 0000:0655 (loc_55)
sub_9B endp
; ---------------------------------------------------------------------------
db 49h ; I
db 6Eh ; n
db 76h ; v
db 61h ; a
db 6Ch ; l
db 69h ; i
db 64h ; d
db 20h
db 70h ; p
db 61h ; a
db 72h ; r
db 74h ; t
db 69h ; i
db 74h ; t
db 69h ; i
db 6Fh ; o
db 6Eh ; n
db 20h
db 74h ; t
db 61h ; a
db 62h ; b
db 6Ch ; l
db 65h ; e
db 0
db 45h ; E
db 72h ; r
db 72h ; r
db 6Fh ; o
db 72h ; r
db 20h
db 6Ch ; l
db 6Fh ; o
db 61h ; a
db 64h ; d
db 69h ; i
db 6Eh ; n
db 67h ; g
db 20h
db 6Fh ; o
db 70h ; p
db 65h ; e
db 72h ; r
db 61h ; a
db 74h ; t
db 69h ; i
db 6Eh ; n
db 67h ; g
db 20h
db 73h ; s
db 79h ; y
db 73h ; s
db 74h ; t
db 65h ; e
db 6Dh ; m
db 0
db 4Dh ; M
db 69h ; i
db 73h ; s
db 73h ; s
db 69h ; i
db 6Eh ; n
db 67h ; g
db 20h
db 6Fh ; o
db 70h ; p
db 65h ; e
db 72h ; r
db 61h ; a
db 74h ; t
db 69h ; i
db 6Eh ; n
db 67h ; g
db 20h
db 73h ; s
db 79h ; y
db 73h ; s
db 74h ; t
db 65h ; e
db 6Dh ; m
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 2Ch ; ,
db 44h ; D
db 63h ; c
db 0AAh ; �
db 0Ah
db 0AAh ; �
db 0Ah
db 0
db 0
db 80h ; �
db 1
db 1
db 0
db 7
db 0FEh ; �
db 0FFh
db 0FFh
db 3Fh ; ?
db 0
db 0
db 0
db 0D9h ; �
db 0A6h ; �
db 3Fh ; ?
db 1
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 0
db 55h ; U
db 0AAh ; �
seg000 ends
end