Assembly 在实际机器上使用int 13h和引导加载程序读取驱动器
嘿,我正在尝试加载一个字符串,该字符串已放置在引导加载程序的末尾或0x7e00。我尝试使用int13h将字符串加载到内存中,然后将其打印到屏幕上。我检查错误,但没有错误发生。然而,没有任何东西可以打印到屏幕上,它只是挂在一个空白屏幕上 以下是我的引导加载程序代码:Assembly 在实际机器上使用int 13h和引导加载程序读取驱动器,assembly,x86,bootloader,Assembly,X86,Bootloader,嘿,我正在尝试加载一个字符串,该字符串已放置在引导加载程序的末尾或0x7e00。我尝试使用int13h将字符串加载到内存中,然后将其打印到屏幕上。我检查错误,但没有错误发生。然而,没有任何东西可以打印到屏幕上,它只是挂在一个空白屏幕上 以下是我的引导加载程序代码: [org 0x7c00] [bits 16] mov byte [driveno], dl ;save dl ;set up stack xor ax, ax cli mov ss, ax mov sp, 0x9000 st
[org 0x7c00]
[bits 16]
mov byte [driveno], dl ;save dl
;set up stack
xor ax, ax
cli
mov ss, ax
mov sp, 0x9000
sti
;set up segment regs
jmp 0x0000:start
start:
xor ax, ax
mov ds, ax
mov es, ax
;reset drive
xor ax, ax
int 0x13
;read 2nd sector
mov al, 0x01
mov bx, 0
mov es, bx
mov bx, 0x7e00
mov cx, 0x0002
xor dh, dh
mov dl, byte [driveno]
mov ah, 0x02
int 0x13
jc read_error ;Apparently no error!!!
mov ah, 0x01 ;Check status of last operation
int 0x13
mov dx, ax ;Print the value stored in ax
call printhex ;This outputs 0x0001 or al=01 so I get an invalid function error?
mov si, 0x7e00 ;print my "loaded" message
call print
mov si, teststr ;test if my print function works, it does.
call print
cli
hlt
jmp $
read_error:
mov si, error
call print
ret
print:
loop:
lodsb
or al, al
jz done
mov ah, 0x0e
mov bx, 0x0003 ;page 0 and default color
int 0x10
jmp loop
done:
ret
printhex: ;This method allows me to see what is inside of registers such as ax.
push bx
push si
mov si, hex_template
mov bx, dx
shr bx, 12
mov bx, [bx+hexabet]
mov [hex_template+2], bl
mov bx, dx
shr bx, 8
and bx, 0x000f
mov bx, [bx+hexabet]
mov [hex_template+3], bl
mov bx, dx
shr bx, 4
and bx, 0x000f
mov bx, [bx+hexabet]
mov [hex_template+4], bl
mov bx, dx
and bx, 0x000f
mov bx, [bx+hexabet]
mov [hex_template+5], bl
call print
pop si
pop bx
ret
error db 'Error',0
teststr db 'Printing works',0
hex_template db '0x????',0 ;For my hex print method
hexabet db '0123456789abcdef' ;Also for my hex print method
driveno db 0 ;Storing dl
times 510-($-$$) db 0
dw 0xaa55
db 'ABCD',0 ;this needs to be loaded
times 1024-($-$$) db 0 ;fill my file so it is 2 whole sectors
我用
nasm -f bin boot.asm -o boot.bin
并且我使用
dd if=boot.bin of=\\.\e: bs=512 count=2
有人知道为什么我的信息在启动usb时没有显示吗?
谢谢 您应该像这样重新排列代码
[org 0x7c00]
[bits 16]
jmp 0x00:0x7c00
start:
;set up stack and segment registers
xor ax, ax
cli
mov ds,ax
mov es,ax
mov ss, ax
mov sp, 0x9000
sti
;Save driveno
mov byte[driveno],dl
;reset drive
xor ax, ax
int 0x13
;read 2nd sector
mov al, 0x01
mov bx, 0
mov es, bx
mov bx, 0x7e00
mov cx, 0x0002
xor dh, dh
mov dl, byte [driveno]
mov ah, 0x02
int 0x13
jc read_error ;Apparently no error!!!
mov ah, 0x01 ;Check status of last operation
int 0x13
mov dx, ax ;Print the value stored in ax
call printhex ;This outputs 0x0001 or al=01 so I get an invalid function error?
mov si, 0x7e00 ;print my "loaded" message
call print
mov si, teststr ;test if my print function works, it does.
call print
cli
hlt
jmp $
read_error:
mov si, error
call print
ret
print:
loop:
lodsb
or al, al
jz done
mov ah, 0x0e
mov bx, 0x0003 ;page 0 and default color
int 0x10
jmp loop
done:
ret
printhex: ;This method allows me to see what is inside of registers such as ax.
push bx
push si
mov si, hex_template
mov bx, dx
shr bx, 12
mov bx, [bx+hexabet]
mov [hex_template+2], bl
mov bx, dx
shr bx, 8
and bx, 0x000f
mov bx, [bx+hexabet]
mov [hex_template+3], bl
mov bx, dx
shr bx, 4
and bx, 0x000f
mov bx, [bx+hexabet]
mov [hex_template+4], bl
mov bx, dx
and bx, 0x000f
mov bx, [bx+hexabet]
mov [hex_template+5], bl
call print
pop si
pop bx
ret
error db 'Error',0
teststr db 'Printing works',0
hex_template db '0x????',0 ;For my hex print method
hexabet db '0123456789abcdef' ;Also for my hex print method
driveno db 0 ;Storing dl
times 510-($-$$) db 0
dw 0xaa55
db 'ABCD',0 ;this needs to be loaded
times 1024-($-$$) db 0 ;fill my file so it is 2 whole sectors
它应该已经解决了您的问题。乍一看是正确的。尽量不要重新加载
dl
,它是由BIOS设置为启动驱动器的-可能它使用软盘模拟,然后它就不会是0x80
。感谢您的回复,是的,我甚至尝试将dl
保存到内存中,稍后再重新加载,仍然不起作用。。。这很奇怪,因为网上所有的东西都说它应该适用于记录,它在qemu
中运行良好。另外,不要将sp
设置为0xffff
,因为使用奇数(未对齐)地址是个坏主意。我怀疑这和你的问题有什么关系,但是,那一定和我的BIOS有关。。。也许qemu设置了一些我不在代码中的东西。当保存DL时,您的代码假设DS=0,在初始化段寄存器后尝试将该行移动到。这里时间还早,但我认为您刚刚发布了错误的代码。BIOS将在7c00:0000或0000:7c00(在实模式下相当)加载此引导扇区。然后您立即执行jmp 0x00:0x7c00
,这将停止所有运行并进入无限循环。@DavidHoelzer我想您的意思是07C0:0000
和0000:7C00
是等效的。只有两件事你应该假设。您的代码将在物理地址0x00007c00
处开始执行,并且DL具有驱动器号。您不能假设CS中的段是什么。虽然0x07C0
和0000
段是常见的,但没有任何东西可以阻止BIOS跳转到像0x2030:5BD0
这样的非球形位置,该位置也映射到物理地址0x00007c00
。)哎哟!是的,我当然知道了。