【问题标题】:Reading from drive using int 13h with bootloader on real machine在真机上使用带有引导加载程序的 int 13h 从驱动器读取
【发布时间】:2015-05-11 08:06:23
【问题描述】:

嘿,我正在尝试加载我放在引导加载程序末尾或 0x7e00 处的字符串。我正在尝试使用 int 13h 将字符串加载到内存中,然后将其打印到屏幕上。我检查错误,但没有发生错误。但是,没有任何内容打印到屏幕上,它只是挂在空白屏幕上。

这是我的引导加载程序代码:

[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

我使用 USB 写信

dd if=boot.bin of=\\.\e: bs=512 count=2

有谁知道为什么当我启动到我的 USB 时我的消息没有显示? 谢谢!

【问题讨论】:

  • 乍一看似乎是正确的。尽量不要重新加载dl,它是由 BIOS 设置为引导驱动器的 - 也许它使用软盘仿真,然后它就不会是 0x80
  • 感谢您的回复,是的,我什至尝试将dl 保存到内存中并稍后重新加载,但仍然无法正常工作......这很奇怪,因为网上的所有内容都说它应该也可以工作跨度>
  • 作为记录,它在qemu 中运行良好。另外,不要将sp 设置为0xffff,因为使用奇数(未对齐)地址是个坏主意。但是,我怀疑这与您的问题有关,
  • 那肯定和我的 BIOS 有关...也许 qemu 正在设置一些我不在我的代码中的东西
  • 您的代码在保存 DL 时假定 DS = 0,请尝试在初始化段寄存器后将该行移至。

标签: assembly x86 bootloader


【解决方案1】:

你应该像这样重新排列你的代码。

    [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

它应该已经解决了你的问题。

【讨论】:

  • 现在还早,但我认为您刚刚发布了损坏的代码。 BIOS 将在 7c00:0000 或 0000:7c00(在实模式下等效)加载此引导扇区。然后您立即执行jmp 0x00:0x7c00,这将停止其轨道中的所有内容并进入无限循环。
  • @DavidHoelzer 我认为你的意思是07C0:00000000:7C00 是等价的。只有两件事你应该假设。您的代码将从物理地址 0x00007c00 开始执行,并且 DL 具有驱动器号。您不能假设 CS 中的段是什么。尽管0x07C00000 的一部分很常见,但没有什么可以阻止BIOS 跳转到像0x2030:5BD0 这样也映射到物理地址0x00007c00 的无球位置。 (2030
  • 哎呀!是的,我确实做到了。
猜你喜欢
  • 2015-07-16
  • 2020-02-22
  • 1970-01-01
  • 2022-07-04
  • 2012-04-12
  • 2012-06-29
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多