Assembly 从硬盘加载扇区时出现问题

Assembly 从硬盘加载扇区时出现问题,assembly,nasm,intel,x86-16,bootloader,Assembly,Nasm,Intel,X86 16,Bootloader,我已经编写了一个MBR引导加载程序,它检测到分区,但无法加载它们。中断13失败了,有人知道我做错了什么吗?我确信这是愚蠢的事情,我已经尝试了好几个小时来修复它 我的引导加载程序代码是: [BITS 16] ;tell the assembler that its a 16 bit code [ORG 0] %define PARTITION_TABLE_START 0x1be %define PARTITION_TABLE_END 0x1ee %define PARTITION_ENTRY_

我已经编写了一个MBR引导加载程序,它检测到分区,但无法加载它们。中断13失败了,有人知道我做错了什么吗?我确信这是愚蠢的事情,我已经尝试了好几个小时来修复它

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

[BITS 16]   ;tell the assembler that its a 16 bit code
[ORG 0]
%define PARTITION_TABLE_START 0x1be
%define PARTITION_TABLE_END 0x1ee
%define PARTITION_ENTRY_SIZE 16
%define COPY_DEST 0x7e00
_begin:
; We must copy the bootloader into a different area of memory
mov ax, 0
mov ds, ax
_copy:
mov si, 0x7c00+_begin
mov di, COPY_DEST
mov cx, 0
._continue:
lodsb
stosb
cmp cx, 0x200
je ._finish
inc cx  
jmp ._continue
._finish:
jmp 0x7e0:_start
_start:
; We are running at 0x7e00 now
mov ax, 0x7e0
mov ds, ax
mov es, ax
mov ss, ax

; Save drive number
mov byte[_drive_no], dl

mov si, _welcome_message
call _print


mov si, _find_message
call _print

mov bx, PARTITION_TABLE_START
_csearch:
cmp byte [bx], 0x80
je _bootable_found
cmp bx, PARTITION_TABLE_END
jae _no_bootable_found
add bx, PARTITION_ENTRY_SIZE
jmp _csearch


_bootable_found:
mov si, _found_message
call _print
; BX Contains current entry position
mov ah, 0x02
mov al, 1
mov dh, [bx+1], ; Head
mov cl, [bx+2] ; Sector
shr cl, 2 ; Ignore bit 6-7 they are not for us
mov ch, [bx+3] ; Cylinder (warning only 8 bits supported)
mov byte dl, [_drive_no] ; Drive number
; Destination: 0x7c00
push ax
mov ax, 0x7c0
mov es, ax
mov bx, 0
pop ax
int 0x13
jc _read_error
mov si, _press_any_key_to_load
call _print
mov ah, 0
int 0x16
; Read success lets jump to the new bootloader
jmp 0x7c0:0

_read_error:
mov si, _read_error_msg
call _print
jmp $

_no_bootable_found:
mov si, _no_partition
call _print
jmp $


_print:
    mov ah, 0x0e
._loop: 
    lodsb
    cmp al, 0
    je ._done
    int 0x10
    jmp ._loop
._done:
    ret
_welcome_message: db 'Welcome to NibbleBits bootloader', 10, 13, 0
_find_message: db 'Will find first active partition', 10, 13, 0
_found_message: db 'Active partition found', 10, 13, 0
_no_partition: db 'No active partition could be found', 10, 13, 0
_read_error_msg: db 'Failed to load partition', 10, 13, 0
_press_any_key_to_load: db 'Press any key to load the partition', 10, 13, 0
_drive_no: db 0

TIMES 510 - ($ - $$) db 0   ;fill the rest of sector with 0
DW 0xAA55           ; add boot signature at the end of bootloader
_end:

结果证明我的代码很好,确实改变了Michael Petch提出的一些事情,但实际加载很好。问题是,当我使用linux的“dd”程序复制引导扇区时,它正在截断整个文件。我通过启用一个标志来防止截断来解决这个问题。

按照论坛规则,您应该在这里提供代码,亲爱的。您可以使用
REP MOVSB
简化整个LODSB/STOSB。但是有了这个beign,said
STOSB
依赖于ES的设置。您可以显示执行
mov-es,ax
以及
mov-ds,ax
。这可能不是一个问题,但首先需要解决的问题是(它可能不适用于所有硬件)但在许多虚拟环境中,它可能已经是0。我假设在您使用此代码创建MBR后,您正在从其他地方将分区表复制到引导加载程序中?是的,Michael,我目前正在一个十六进制编辑器中手动输入分区表,我编写了一个程序为我执行此操作,但它有一些错误,我做这件事的时候就像是早上5点,哈哈,可能是一些简单的事情。你们谁能看到我的问题吗。我相信我的想法是正确的。在此搜索:
shr cl,2
将扇区号除以4。你真的确定这就是你想要的吗?如果您的目的是简单地将位6和7归零,那么您的意思可能是
和cl,0x3f
?更好的是,在从分区表中获取这些值之后,我不会对它们做任何处理。按原样读入dh、cl、ch。