x86: INT 13h does not read from the disk

I tried to load kernel stored on floppy disk formatted to FAT12. When I try to read sectors where kernel is located, I don’t have any errors (carry flag is not set), but memory where I try to load the kernel has zeroes.

org 0x7C00
bits 16

%define endl            0x0D, 0x0A
%define dirEntrySize        32
%define fatLocation     0x7E00
%define rootdirLocation     0x9000
%define kernelLocation      0x9E00
%define filenameLength      11

jmp short main
nop

; BPB and EBR data here

rootdirStart:           dw 0
dataStart:          dw 0

main:
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0x7C00

    mov [ebr_driveNumber], dl

    mov si, msg_loading
    call puts

    ; Read FAT
    mov ax, [bpb_reservedSectors]
    mov bx, fatLocation
    mov cx, [bpb_sectorsPerFat]
    call readSectors
    
    ; Read Root Directory
    mov ax, [bpb_rootdirEntries]
    mov bx, dirEntrySize
    mul bx
    div word [bpb_bytesPerSector]
    mov [dataStart], ax
    xchg ax, cx
    mul byte [bpb_fatCount]
    add ax, [bpb_reservedSectors]
    mov bx, rootdirLocation
    call readSectors
    mov [rootdirStart], ax
    add [dataStart], ax
    
    ; Find and read the kernel
    mov si, kernelFilename
    call findFile
    mov bx, kernelLocation
    call readFile

    ; Load kernel
    mov dl, [ebr_driveNumber]
    jmp kernelLocation

    cli
    hlt

; putc and puts functions

lbaToChs:
    push ax
    push dx
    xor dx, dx
    div word [bpb_sectorsPerTrack]
    inc dx
    mov cx, dx
    xor dx, dx
    div word [bpb_headCount]
    mov dh, dl
    mov ch, al
    shl ah, 6
    or cl, ah
    pop ax
    mov dl, al
    pop ax
    ret

readSectors:
    push ax
    push cx
    push dx
    push si
    push di
    push cx
    call lbaToChs
    pop si
    mov di, 3
    mov dl, [ebr_driveNumber]
.loop:
    mov ah, 0x02
    int 0x13
    mov ah, 0x01
    int 0x13
    jnc .done
    mov ah, 0x00
    int 0x13
    dec di
    jz .fail
    dec si
    jnz .loop
.done:
    pop di
    pop si
    pop dx
    pop cx
    pop ax
    ret
.fail:
    mov si, msg_diskError
    call puts
    cli
    hlt

; findFile function

readFile:
    push ax
    push bx
    push cx
    push dx
.loop:
    push ax
    sub ax, 2
    mul byte [bpb_sectorsPerCluster]
    add ax, word [dataStart]
    mov cx, 1
    call readSectors
    mov ax, [bpb_bytesPerSector]
    mul byte [bpb_sectorsPerCluster]
    add bx, ax
    pop ax
    mov cl, 3
    mul cx
    dec cl
    div cx
    mov si, fatLocation
    add si, ax
    mov ax, [si]
    or dx, dx
    jnz .odd
.even:
    and ax, 0x0FFF
    jmp .update
.odd:
    shr ax, 4
.update:
    cmp ax, 0xFF0
    jnl .loop
.done:
    pop dx
    pop cx
    pop bx
    pop ax
    ret
.fail:
    mov si, msg_loadFailed
    call puts
    cli
    hlt

kernelFilename: db "KERNEL  BIN"
msg_loading: db "Loading...", endl, 0
msg_findFailed: db "Cannot find kernel", 0
msg_loadFailed: db "Cannot load kernel", 0
msg_diskError: db "Disk error", 0

times 510+$$-$ db 0
dw 0xAA55

I tried debugging with GDB and checked the registers, but their value was correct. I also checked the memory where I stored the FAT and the Root Directory, but this data also was correct. Only the memory where I wanted to load kernel was filled with zeroes.

Register values after lba-to-chs conversion:

eax            0x21                33
ecx            0x10                16
edx            0x100               256
ebx            0x9e00              40448
esp            0x7be6              0x7be6
ebp            0x0                 0x0
esi            0x7d98              32152
edi            0x0                 0
eip            0x7ce6              0x7ce6
eflags         0x202               [ IOPL=0 IF ]
cs             0x0                 0
ss             0x0                 0
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0

AX value is correct, should be lba of start of data: reserved_sectors + sectors_per_fat * fat_count + root_dir_entries * dir_entry_size / bytes_per_sectors = 1 + 9 * 2 + 224 * 32 / 512 = 1 + 18 + 14 = 33. In floppy image opened with hex editor, that points to start of the kernel.

Loaded file allocation table:

0x7e00: 0xf0    0xff    0xff    0xff    0x0f    0x00    0x00    0x00
0x7e08: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
...

Loaded root directory:

0x9000: 0x4b    0x45    0x52    0x4e    0x45    0x4c    0x20    0x20
0x9008: 0x42    0x49    0x4e    0x20    0x18    0x00    0x28    0x61
0x9010: 0xaa    0x58    0xaa    0x58    0x00    0x00    0x28    0x61
0x9018: 0xaa    0x58    0x02    0x00    0x25    0x01    0x00    0x00
0x9020: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x9028: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x9030: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x9038: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
...

*Loaded* kernel:

0x9e00: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x9e08: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x9e10: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x9e18: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
...

New contributor

Grigaror is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật