int 0x13,ah = 0x08,获取驱动器参数

时间:2016-01-01 09:56:00

标签: assembly x86 operating-system nasm real-mode

我正在尝试在x86中编写一个简单的命令系统来运行简单的.COM文件。此命令系统旨在从720KB软盘启动。这是代码:

[BITS 16]
[ORG 0x0000]      

mov ax, cs
mov ds, ax   
mov [drive_num], dl
mov [root_drive], dl
mov bx, load_msg
call str_prt
call new_line
xor cx, cx  
mov bx, art1
call str_prt
call new_line
mov bx, art2
call str_prt
call new_line
mov bx, art3
call str_prt
call new_line
mov bx, art4
call str_prt
call new_line
mov bx, art5
call str_prt
call new_line
mov bx, art6
call str_prt
call new_line
mov bx, art7
call str_prt
call new_line
call new_line
mov bx, welcome_msg
call str_prt
call new_line
mov bx, creator_msg
call str_prt
call new_line
mov bx, boot_msg
call str_prt
mov bx, disk
call str_prt
call disk_prop
call new_line

mov bx, [buffer]

call new_line

mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
mov al, '>'
int 0x10

loop:
xor ah, ah
int 0x16
call key_scan
jmp loop

%include "util.inc"

pro_com:
push bx
push ax
mov bx, buffer
mov al, [bx]
cmp al, 'h'
jne help_end
inc bx
mov al, [bx]
cmp al, 'e'
jne help_end
inc bx
mov al, [bx]
cmp al, 'l'
jne help_end
inc bx
mov al, [bx]
cmp al, 'p'
jne help_end
call com_help
jmp pro_end
help_end:
mov bx, buffer
mov al, [bx]
cmp al, 'd'
jne dir_end
inc bx
mov al, [bx]
cmp al, 'i'
jne dir_end
inc bx
mov al, [bx]
cmp al, 'r'
jne dir_end
call com_dir
jmp pro_end
dir_end:
mov bx, buffer
mov al, [bx]
cmp al, 'o'
jne open_end
inc bx
mov al, [bx]
cmp al, 'p'
jne open_end
inc bx
mov al, [bx]
cmp al, 'e'
jne open_end
inc bx
mov al, [bx]
cmp al, 'n'
jne open_end
call com_open
jmp pro_end
open_end:
mov bx, not_found
call str_prt
call new_line
pro_end:
pop ax
pop bx
ret

com_help:
push bx
call new_line
call draw_line
mov bx, dir_help
call str_prt
call new_line
call draw_line
call new_line
pop bx
ret

com_dir:
call new_line
push ax
push bx
push cx
push dx
call new_line
call draw_line
mov bx, drive_num
mov dl, [bx]
mov al, 0x01
mov ch, 0x00
mov cl, 0x01
mov dh, 0x00
com_dir_loop:
call read_dir
cmp cl, 0xff
je false1
inc cl
jmp com_dir_loop
false1:
cmp ch, 0xfe
je false2
inc ch
xor cl, cl
add cl, 0x01
jmp com_dir_loop
false2:
cmp dh, 0x01
je false3
xor cx, cx
add cl, 0x0f
inc dh
jmp com_dir_loop
false3:
call draw_line
call new_line
pop dx
pop cx
pop bx
pop ax 
ret

read_dir:
push ax
push bx
mov bx, 0x1000
mov es, bx
mov bx, 0xe00
;call screen_pause
;call disk_print
;call new_line
call read_disc
clc
mov bx, 0x0ff0
mov al, [bx]
cmp al, 'F'
jne read_dir_end
mov bx, 0x0ff1
call str_prt
call new_line
read_dir_end:
pop bx
pop ax 
mov bx, 0x1000
mov es, bx
ret


;---------------------------------------------------------------
;Construction zone

com_open:
push ax
push bx
push cx
push dx
call new_line
call draw_line
mov bx, drive_num
mov dl, [bx]
mov al, 0x01
mov ch, 0x00
mov cl, 0x01
mov dh, 0x00
com_open_loop:
call read_open
cmp cl, 0x09
je open_false1
inc cl
jmp com_open_loop
open_false1:
cmp ch, 0x4e
je open_false2
inc ch
xor cl, cl
add cl, 0x01
jmp com_open_loop
open_false2:
cmp dh, 0x01
je open_false3
xor cx, cx
add cl, 0x01
inc dh
jmp com_open_loop
open_false3:
call new_line
call draw_line
call new_line
pop dx
pop cx
pop bx
pop ax 
ret

read_open:
push cx
push ax
push bx
mov bx, 0x1000
mov es, bx
mov bx, 0xe00
call read_disc
clc

mov bx, buffer
add bx, 0x05
mov al, [0x0ff0]
cmp al, 'F'
jne read_open_end

mov al, [0x0ff1]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff2]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff3]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff4]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff5]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff6]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff7]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff8]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ff9]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ffa]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

mov al, [0x0ffb]
mov cl, [bx]
cmp al, cl
jne read_open_end
inc bx

clc
call 0x0e00
clc
call new_line
read_open_end:
mov bx, 0x1000
mov es, bx
pop bx
pop ax
pop cx 
ret


;---------------------------------------------------------------

buffer times 20 db 0
disk_buffer times 20 db 0

drive_num:
db 0
root_drive:
db 0

welcome_msg:
db 'Welcome to matriXos$'
creator_msg:
db 'Created by Vishnu Shankar.B$'
boot_msg:
db 'Booting command line interface...$'
not_found:
db '<Error>Command cannot be resolved! Use command "help"$'
dir_help:
db '    dir - Lists files in a drive$'
line:
db '==============================$'
art1:
db '                        __                     __   __                      $'
art2:
db '                       /\ \__           __    /\ \ /\ \                    $'
art3:
db '  ___ ___       __     \ \ ,_\   _ __  /\_\   \ `\`\/#/#     ___     ____  $'
art4:
db '/# __` __`\   /#__`\    \ \ \/  /\`#__\\/\ \   `\/ > <      / __`\  /#,__\ $'
art5:
db '/\ \/\ \/\ \ /\ \L\.\_   \ \ \_ \ \ \/  \ \ \     \/#/\`\  /\ \L\ \/\__, `\$'
art6:
db '\ \_\ \_\ \_\\ \__/.\_\   \ \__\ \ \_\   \ \_\    /\_\\ \_\\ \____/\/\____/$'
art7:
db ' \/_/\/_/\/_/ \/__/\/_/    \/__/  \/_/    \/_/    \/_/ \/_/ \/___/  \/___/ $'
load_msg:
db 'Successfully loaded operating system$'
disk:
db 'Disk properties: $'

jmp $
times 3584 - ($ - $$) db 0

这是util.inc:

key_scan:
cmp al, 0x08
je back_space
cmp al, 0x0d
je enter
cmp cx, 0x0015 
je end
mov ah, 0x0e
int 0x10
mov bx, buffer
add bx, cx
mov [bx], al
inc cx
jmp end
back_space:
cmp cx, 0x00
je end
dec cx
mov ah, 0x0e
mov al, 0x08
int 0x10
mov al, 0x20
int 0x10
mov al, 0x08
int 0x10
jmp end
enter:
xor cx, cx
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
call pro_com
call clear_buffer
mov ah, 0x0e
mov al, '>'
int 0x10
end:
ret

clear_buffer:
push ax
push bx
push cx
mov bx, buffer
xor cx, cx
xor ax, ax
start:
cmp cx, 0x41
je end_buff
mov [bx], ax
inc bx
inc cx
jmp start
end_buff:
pop cx
pop bx
pop ax
ret

str_prt:
pusha
str:
mov ah, 0x0e
mov al, [bx]
cmp al, '$'
je str_end
int 0x10
add bx, 1
jmp str
str_end:
popa
ret

draw_line:
push ax
push bx
line_str:
mov bx, line
call str_prt
call new_line
pop bx
pop ax
ret

new_line:
push ax
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
pop ax
ret

read_disc:
mov ah, 0x02   
int 0x13   
ret

disk_prop:
push ax
push bx
push cx
push dx
mov dl, [drive_num]
mov ah, 0x08
mov bx, 0x0000
mov es, bx
mov di, bx
int 0x13
call hex_print
mov cx, dx
call hex_print
mov bx, 0x1000
mov es, bx
pop dx
pop cx
pop bx
pop ax
ret

disk_print:
push cx
mov cx, ax
call hex_print
pop cx
call hex_print
push cx
mov cx, dx
call hex_print
pop cx
ret

hex_print:
push ax
push cx
mov ah, 0x0e
mov al, '0'
int 0x10
mov al, 'x'
int 0x10
hex_print_start:
mov al, ch
and al, 0xf0
call hex_map
int 0x10
shl cx, 0x04
mov al, ch
and al, 0xf0
call hex_map
int 0x10
shl cx, 0x04
mov al, ch
and al, 0xf0
call hex_map
int 0x10
shl cx, 0x04
mov al, ch
and al, 0xf0
call hex_map
int 0x10
hex_print_end:
pop cx
pop ax
ret

hex_map:
cmp al, 0x00
jne zero_end
mov al, '0'
ret
zero_end:
cmp al, 0x10
jne one_end
mov al, '1'
ret
one_end:
cmp al, 0x20
jne two_end
mov al, '2'
ret
two_end:
cmp al, 0x30
jne three_end
mov al, '3'
ret
three_end:
cmp al, 0x40
jne four_end
mov al, '4'
ret
four_end:
cmp al, 0x50
jne five_end
mov al, '5'
ret
five_end:
cmp al, 0x60
jne six_end
mov al, '6'
ret
six_end:
cmp al, 0x70
jne seven_end
mov al, '7'
ret
seven_end:
cmp al, 0x80
jne eight_end
mov al, '8'
ret
eight_end:
cmp al, 0x90
jne nine_end
mov al, '9'
ret
nine_end:
cmp al, 0xa0
jne a_end
mov al, 'A'
ret
a_end:
cmp al, 0xb0
jne b_end
mov al, 'B'
ret
b_end:
cmp al, 0xc0
jne c_end
mov al, 'C'
ret
c_end:
cmp al, 0xd0
jne d_end
mov al, 'D'
ret
d_end:
cmp al, 0xe0
jne e_end
mov al, 'E'
ret
e_end:
cmp al, 0xf0
jne f_end
mov al, 'F'
ret
f_end:
ret

screen_pause:
push ax
xor ax, ax
int 0x16
pop ax
ret

这在bochs模拟器中工作正常。我希望这是从闪存驱动器运行。所以我在util.inc中编写了一个函数disk_prop。该函数在comandsys.asm中的程序开头调用(第40-44行)。这个函数调用ah = 0x08,int 0x13并在cx中输出值,然后在十六进制寄存器中打印十六进制寄存器,以便我可以获得闪存驱动器中的扇区数,磁头数,柱面数。我在我的笔记本电脑上运行了这个程序,找到了我的闪存驱动器中扇区,柱面,轨道的数量,然后相应地更改了comandsys.asm中的com_dir函数。 com_dir函数应该打印在每个扇区的“End”以字母“F”开头的字符串。更改后,我通过我的闪存驱动器启动了我的笔记本电脑,但com_dir功能打印垃圾! sombody可以告诉我有什么问题吗? 提前谢谢!
对于我的Bootloader,click on this stack overflow question
注意:忽略“建筑区域”

0 个答案:

没有答案