Assembly 引导加载程序在实际计算机上不工作

Assembly 引导加载程序在实际计算机上不工作,assembly,x86,nasm,bootloader,bare-metal,Assembly,X86,Nasm,Bootloader,Bare Metal,我知道以前有人问过这个问题,但其他答案似乎都没有解决我的问题。也许我错过了什么 我知道.iso是有效的,因为我在QEMU中运行了它,它成功地工作了。那么我做错了什么 bits 16 xor ax, ax start: cld ; Set direction flag to forward ; Set up registers mov ax, 07c0h ; Segment location which BIOS loads

我知道以前有人问过这个问题,但其他答案似乎都没有解决我的问题。也许我错过了什么

我知道.iso是有效的,因为我在QEMU中运行了它,它成功地工作了。那么我做错了什么

bits 16

xor ax, ax

start:
    cld               ; Set direction flag to forward

    ; Set up registers
    mov ax, 07c0h     ; Segment location which BIOS loads
    add ax, 288       ; (4096 + 512) / 16 bytes
    mov ss, ax        ; Sets stack segment register
    mov sp, 4096      ; Sets stack pointer register (offset of stack)

    mov ax, 07c0h
    mov ds, ax        ; Sets data segment to where we're loaded

    mov si, text      ; Puts string into source index
    call print_string ; Calls print string

    jmp $             ; Infinite loop to prevent shutdown

print_string:
    mov ah, 0eh       ; System call for printing
    xor bh, bh        ; Sets BH register to 0

.repeat:
    lodsb             ; Loads byte into AL
    cmp al, 0         ; Sees if AL is 0
    je .done          ; Jumps to done if AL is zero

    int 10h           ; Otherwise, print
    jmp .repeat       ; Repeat

.done:
    ret

text db 'Test', 0

times 510 - ($ - $$) db 0 ; Pads 510 - (current location - start location) zeros
dw 0xAA55                 ; Standard PC boot signature (takes up 2 bytes)
编辑:我已将以下内容添加到我的代码中:

xor ax, ax
cld
xor bh, bh
为了创建iso,我运行以下命令:

dd if=/dev/zero of=floppy.img bs=1024 count=1440
dd if=bootloader.bin of=floppy.img seek=0 count=1 conv=notrunc
mkdir iso
cp floppy.img iso/
mkisofs -o file.iso -b floppy.img iso
umount /dev/sdX
dd if=/home/mint/Downloads/file.iso of=/dev/sdX bs=4M && sync
为了将iso刻录到我的usb,我运行以下命令:

dd if=/dev/zero of=floppy.img bs=1024 count=1440
dd if=bootloader.bin of=floppy.img seek=0 count=1 conv=notrunc
mkdir iso
cp floppy.img iso/
mkisofs -o file.iso -b floppy.img iso
umount /dev/sdX
dd if=/home/mint/Downloads/file.iso of=/dev/sdX bs=4M && sync
您的问题是,您创建的“iso”是光盘映像。只有当它刻录到光盘(如CD-R)上时,才能在真正的计算机上启动。当您将其与QEMU一起使用时,您显然将其用作模拟CD-ROM。当您将其复制到USB驱动器时,它的格式不适合在USB驱动器上引导

幸运的是,从USB驱动器引导的正确格式很简单:引导加载程序只需要位于驱动器的第一个扇区,就像在软盘或硬盘上一样。因此,您可以跳过创建“iso”部分,直接将引导扇区写入USB驱动器。例如:

dd if=bootloader.bin of=/dev/sdX 

要在实际计算机上启动“.iso”,您到底在做什么?您可能希望使用CLD向前设置方向标志,因为您依赖于LODSB的向前方向。您无法保证BIOS在到达coe之前设置了什么方向。因为您可能希望将BH寄存器设置为0,因为它用作要写入的页码。启动时是否使用了CD-ROM?(我这样问是因为你提到你制作了ISO,但不清楚你是否在真正的PC上刻录了一张物理CD)。我很好奇你启动QEMU的命令行是什么样子的。真正的硬件,特别是EFI CSM,需要做额外的检查:也许OP被“混合”ISO映像现在在Linux“live cd”映像中很常见的事实弄糊涂了:你可以
dd
将它们放到USB设备上,因为它们看起来像一个有效的分区表,也像一个可引导的ISO9660映像,并且SysLinux3.72和更高版本支持从此分区表引导。(但主要是使用
isohybrid
命令。)