Это исправленный код, который при запуске будет выполняться в соответствии с ожидаемыми результатами. Эта программа будет отображать файлы и каталоги, хранящиеся в FAT12, сын программы проводника файлов
Вот код:
[org 0x4000] ; my bootloader loaded us at loc 0x00:0x4000, so this will be our starting loc of our code
[bits 16]
xor ax, ax
mov ds, ax
mov es, ax
mov bp, 0x9000
mov sp, bp ; set the stack at the top of our code
%macro set_cursor 2
mov ah, 0x02
xor bh, bh
mov dl, %1
mov dh, %2
int 10h
%endmacro
%macro get_pos 0
mov ah, 03h
xor bh, bh
int 10h
%endmacro
mov ax, 0010h
int 10h
mov dl, 0
mov [drive_letter], dl
mov ah, 8
mov dl, [drive_letter]
int 13h
jc read_error
and cx, 3fh
mov [SectorsPerTrack], cx
movzx dx, dh ; high word has been zeroed out
add dx, 1
mov [Head], dx
xor ax, ax
mov dl, [drive_letter]
int 13h
jc read_error
;#calculating the root start
mov ax, 19 ; root directory logical block begins at 19th sector
mov [root_start], ax ; now we have the starting sector of the root directory
;#load root director entry into memory sector by sector
mov cx, 14
mov ax, [root_start]
xor bx, bx
mov es, bx
read_next_sector:
push cx
push ax ; store lba address in the stack
mov bx, 0x5000
mov [entry_pointer], word 0
call read_sectors
check_if_empty:
mov al, [bx]
cmp al, 0xe5 ; thats a deleted file skip it
je read_next_entry
mov al, [bx]
cmp al, 0x00 ; there z no file here skip it
je read_next_entry
mov al, [bx+0x08]
cmp al, 'B' ; wE WANT BINARY Files only
jne read_next_entry
mov al, [bx+0x0b]
cmp al, 0x0f
je read_next_entry ; just skip the long file names
mov al, [bx+0x0b]
cmp al, 0x10 ; if it is a folder not a file skip it
je read_next_entry
mov al, [bx+0x0b]
cmp al, 0x08 ; if it is a volume label not a file skip it
je read_next_entry
mov al, [bx+0x0b]
cmp al, 0x04 ; if it is a volume label not a file skip it
je read_next_entry
mov al, [bx+0x0b]
cmp al, 0x02 ; if it is a volume label not a file skip it
je read_next_entry
inc word [no_files] ; get number of files
mov si, bx ; copy entry
mov di, existing_files ; the location of root directory entry
add di, [next_section]
mov cx, 32 ; copy the whole entry
cld
rep movsb
add [next_section], word 32 ; skip by size of each entry to avoid overriding
read_next_entry:
add [entry_pointer], word 32
add bx, 32 ; point to the next entry
cmp [entry_pointer], word 512 ; have we exceeded the sector size if yes execute the code below
jnae check_if_empty
pop ax ; retrieve the current logical address from the stack
pop cx ; retrieve count from the stack
inc ax ; load next sector when we loop back again
loop read_next_sector
jmp _done
_done:
mov cx, [no_files]
mov [save_no], word cx
call update_menu
jmp show_h_item ; default highlighted item on the menu
h_item: ; highlight the desired item using up or down keys
xor ah, ah
int 16h
cmp ah, 0x48 ; up_key
je dec_index
cmp ah, 0x50
je inc_index ; down key
cmp ah, 0x1c ; Enter key
je execute_file
jmp h_item
inc_index:
add [file_pointer], word 32 ; points to the actual entry
jmp show_h_item
dec_index:
sub [file_pointer], word 32 ; points to the actual entry
jmp show_h_item
show_h_item:
call update_menu
mov dx, [file_pointer]
shr dx, 4 ; same as (file_pointer value / 32) * 2
xchg dl, dh
set_cursor 1, dh
mov dx, existing_files
add dx, [file_pointer]
mov cx, 11
mov bl, 4
call print_string
jmp h_item
execute_file:
pusha
mov bx, existing_files
add bx, [file_pointer] ; get details of the selected file entry
mov cx, [bx+0x1a] ; get first cluster number of a file
xor ax, ax
mov es, ax ; set es segment to zero
mov bx, 0x8000 ; load our file at location 0x00:0x4500
read_file_next_sector:
mov ax, cx ; copy cluster number to ax - lba register
add ax, 31 ; align our cluster with the data area
push cx
call read_sectors
pop cx
add bx, 512
mov ax, cx
shr ax, 1
add ax, cx
mov si, ax ; copy cluster number to si
mov dx, [0x1000+si] ; get cluster number or end_of_file byte from fat table
test cx, 1
jnz .odd
and dx, 0fffh
jmp .done
.odd:
shr dx, 4
.done:
mov cx, dx
cmp cx, 0xff8
jl read_file_next_sector
mov ah, 0x0e
xor bh, bh
mov al, '='
mov bl, 15
int 10h
jmp 0x00:0x8000
jmp $
update_menu:
mov [pointer], word 0
mov cx, [save_no]
mov [no_files], word cx ; will fix this when we return
set_cursor 1, 0
mov dh, 0
.display_files1:
set_cursor 1, dh
mov dx, existing_files
add dx, [pointer]
mov cx, 11
mov bl, 15 ; white on text
call print_string
add [pointer], word 32 ; get the next entry
dec word [no_files]
get_pos
add dh, 2
cmp [no_files], word 0
jne .display_files1
ret
print_string:
sub dx, 1
.print_char:
push cx
inc dx
mov ah, 0x0e
mov si, dx
mov al, [si]
xor bh, bh
int 10h
pop cx
loop .print_char
ret
jmp $
read_error:
mov ah, 0x0e
xor bh, bh
mov al, 'R'
int 10h
xor ah, ah
int 16h
int 19h
hlt
jmp $
read_sectors:
push ax
push bx
xor dx, dx
mov bx, [SectorsPerTrack]; sectors per track
div bx
inc dx
mov cl, dl
xor dx, dx
mov bx, [Head] ; number of heads
div bx
mov ch, al
xchg dl, dh
;call other function routines
mov ah, 2
mov al, 1
pop bx
mov dl, [drive_letter]
int 13h
jc read_error
pop ax ; restore logical block address before exiting the read_sector routine
ret
drive_letter db 0
SectorsPerTrack dw 0
Head dw 0
root_size dw 14
root_start dw 0
entry_pointer dw 0
next_section dw 0
next_sectionb dw 0
no_files dw 0
save_no dw 0
pointer dw 0
file_pointer dw 0
file_name db 'KERNEL BIN', 0
existing_files: