gpt4 book ai didi

assembly - INT 0x13/AH = 0x02 适用于软盘镜像,但不适用于在闪存驱动器上刻录

转载 作者:行者123 更新时间:2023-12-02 20:02:01 25 4
gpt4 key购买 nike

我正在尝试在 x86 程序集中创建一个简单的命令系统。命令系统是第二阶段,加载于0x1000:0000。要查看我的引导加载程序,请单击 on this stackoverflow question .

这是第二阶段的命令系统:



[BITS 16]
[ORG 0x0000]

mov ax, cs
mov ds, ax
xor cx, cx
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
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:
in al, 64h
test al, 1
je loop
xor ah, ah
int 0x16
call key_scan
jmp loop

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

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

new_line:
push ax
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
pop ax
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

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, not_found
call str_prt
call new_line
pro_end:
pop ax
pop bx
ret

com_help:
push bx
call new_line
mov bx, help1_msg
call str_prt
call new_line
call new_line
pop bx
ret

com_dir:
push ax
push bx
push cx
push dx
mov bx, drive_num
mov dl, [bx]
mov cl, 0x09
mov al, 0x01
mov ch, 0x00
mov cl, 0x09
mov dh, 0x00
com_dir_loop:
call read_dir
cmp cl, 0x12
je false1
inc cx
jmp com_dir_loop
false1:
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 read_disc
clc
mov bx, 0x0e00
mov al, [bx]
cmp al, 'F'
jne read_dir_end
;print file name
mov bx, 0x0e01
call str_prt
call new_line
;----
read_dir_end:
pop bx
pop ax
mov bx, 0x1000
mov es, bx
ret

read_disc:
mov ah, 0x02
int 0x13
ret

buffer times 20 db 0

drive_num:
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 'Command cannot be resolved!$'
help1_msg:
db 'Help not avilable!$'


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




命令“dir”(com_dir)应该读取并打印以字母“F”开头的字符串,该字符串放在每个扇区 9 - 18(磁道 0)(CHS)的开头。我已在十六进制编辑器的帮助下将字符串放置到位。
我将代码转换为图像文件。它在 Bochs 模拟器中工作正常,但是当我将镜像文件刻录到闪存驱动器上并在计算机中启动它时,它会打印垃圾。
有人可以告诉我出了什么问题吗?
提前致谢。

最佳答案

在我的previous answer ,我碰巧删除了引导加载程序中将 DL 设置为零的行。您的引导加载程序执行了以下操作:

mov dl,0x0  ;Drive = 0 (Floppy)

这需要删除。我现在在之前的回答中通过以下评论给出了这样做的原因:

This hard codes the boot drive to the Floppy A:. If you boot off of USB, hard drive, or Floppy B: your code won't work because the drive number likely won't be zero in those cases. The BIOS passes the actual boot drive that was used to load your bootloader. That value is in the register DL. This is the value you should be using for BIOS disk functions. Since DL already contains the boot drive, we just use it as-is.

重用DL中传递给引导加载程序的值以进行驱动器读写,同时也将此值传递给第二阶段!由于引导加载程序实际上不会破坏 DL 的内容,因此您只需将 DL 移动到 drive_num 变量中即可。您可以在第二阶段设置 DS 寄存器后立即执行此操作,如下所示:

[BITS 16]
[ORG 0x0000]

mov ax, cs
mov ds, ax
mov [drive_num], dl ; drive_num = the boot drive the BIOS booted from

如果您修改了引导加载程序,导致其破坏了DXDL寄存器的内容,那么您应该考虑在引导加载程序启动后将其推送到堆栈上,并且然后在跳转到第二阶段之前将其弹出(恢复)。

在我在上一个答案中向您展示的引导加载程序中,我是这样启动的:

xor ax, ax
mov ds, ax ; DS=0

cli ; Turn off interrupts for SS:SP update
; to avoid a problem with buggy 8088 CPUs
mov ss, ax ; SS = 0x0000
mov sp, 0x7c00 ; SP = 0x7c00
; We'll set the stack starting just below
; where the bootloader is at 0x0:0x7c00. The
; stack can be placed anywhere in usable and
; unused RAM.
sti ; Turn interrupts back on

设置堆栈后,我们可以通过执行以下操作保存DX寄存器:

xor ax, ax
mov ds, ax ; DS=0

cli ; Turn off interrupts for SS:SP update
; to avoid a problem with buggy 8088 CPUs
mov ss, ax ; SS = 0x0000
mov sp, 0x7c00 ; SP = 0x7c00
; We'll set the stack starting just below
; where the bootloader is at 0x0:0x7c00. The
; stack can be placed anywhere in usable and
; unused RAM.
sti ; Turn interrupts back on
push dx ; Save DX register (which includes DL) on stack

现在它已被保存,我们可以在跳转到第二阶段之前恢复它的值。这段代码:

jmp 0x1000:0000   ; Jump to 0x1000, start of second stage

现在会这样做:

pop dx            ; Restore DX register (which includes DL)
jmp 0x1000:0000 ; Jump to 0x1000, start of second stage

这有效地将DL(引导驱动器)传递到我们的第二阶段,即使我们可能在执行引导加载程序期间破坏其内容。然后,我们的第二阶段能够重用该值来执行自己的 BIOS 磁盘读写操作。

关于assembly - INT 0x13/AH = 0x02 适用于软盘镜像,但不适用于在闪存驱动器上刻录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34202607/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com