Assembly 带MASM的2阶段引导加载程序
下面是我的引导扇区和内核代码 我正在使用int 13 func 42将我的引导扇区从usb加载到1000:00(小时) 我跳到内核 但是在加载内核之后总是什么都没有发生Assembly 带MASM的2阶段引导加载程序,assembly,x86,kernel,masm,bootloader,Assembly,X86,Kernel,Masm,Bootloader,下面是我的引导扇区和内核代码 我正在使用int 13 func 42将我的引导扇区从usb加载到1000:00(小时) 我跳到内核 但是在加载内核之后总是什么都没有发生 ;------------------------------------------------------------ .286 ; CPU type ;--------------------------------------------------------
;------------------------------------------------------------
.286 ; CPU type
;------------------------------------------------------------
.model TINY ; memory of model
;---------------------- EXTERNS -----------------------------
extrn _BootMain:near ; prototype of C func
;------------------------------------------------------------
;------------------------------------------------------------
.code
org 07c00h ; for BootSector
main:
jmp short start ; go to main
nop
;----------------------- Vairiables -----------------------
BiosDriveID db 0
;----------------------- CODE SEGMENT -----------------------
start:
cli
mov [BiosDriveID],dl
mov ax,cs ; Setup segment registers
mov ds,ax ; Make DS correct
mov es,ax ; Make ES correct
mov ss,ax ; Make SS correct
mov bp,7c00h
mov sp,7c00h ; Setup a stack
sti
;call _BootMain
mov si, OFFSET msgLoading
call DisplayMessage
;*************************************************************************
; Setup DISK ADDRESS PACKET
;*************************************************************************
mov si, OFFSET msgDAPACK
call DisplayMessage
jmp strtRead
DAPACK:
db 010h ; Packet Size
db 0 ; Always 0
blkcnt:
dw 1 ; Sectors Count
db_add:
dw 01000h ; Transfer Segment
dw 0h ; Transfer Offset
d_lba:
dd 1 ; Starting LBA (0 - n)
dd 0 ; Bios 48 bit LBA
;*************************************************************************
; Start Reading Sectors using INT13 Func 42
;*************************************************************************
strtRead:
mov si, OFFSET msgSectors
call DisplayMessage
mov si, OFFSET DAPACK
mov ah,042h
mov dl,[BiosDriveID]
int 013h
jc readError
jmp readOK
;*************************************************************************
; Sectors Reading Error
;*************************************************************************
readError:
mov si,OFFSET msgFailure
call DisplayMessage
hlt
;*************************************************************************
; Sectors Reading OK
;*************************************************************************
readOK:
mov si, OFFSET msgReadOK
call DisplayMessage
mov ax,01000h
mov ds,ax ; Make DS correct
mov es,ax ; Make ES correct
mov ss,ax ; Make SS correct
db 09Ah
dw 0000h
dw 1000h
;mov si, OFFSET msgLoading
;call DisplayMessage
;call farKernel
;push 1000h
;push 0000h
;retf
hlt
ret
;*************************************************************************
; PROCEDURE DisplayMessage
; display ASCIIZ string at ds:si via BIOS
;*************************************************************************
DisplayMessage proc near
lodsb ; load next character
or al, al ; test for NUL character
jz DONE
mov ah, 00Eh ; BIOS teletype
mov bh, 000h ; display page 0
mov bl, 007h ; text attribute
int 010h ; invoke BIOS
jmp DisplayMessage
DONE:
ret
DisplayMessage endp
;*************************************************************************
;*******************************************************************************
;messages that needs to be shown
msgLoading:
db 00Dh, 00Ah, "******************************************"
db 00Dh, 00Ah, "* AFME Operating System Version 1.00... *"
db 00Dh, 00Ah, "******************************************", 00Dh, 00Ah,000h
msgDAPACK db 00Dh, 00Ah, "Setup Disk Addressing Packet...", 00Dh, 00Ah, 000h
msgSectors db 00Dh, 00Ah, "Start Loading Sectors...", 00Dh, 00Ah, 000h
msgFailure db 00Dh, 00Ah, "Kernel loading failed...", 00Dh, 00Ah, 000h
msgReadOK db 00Dh, 00Ah, "Kernel loading succeded...", 00Dh, 00Ah, 000h
msgCRLF db 00Dh, 00Ah, 000h
db 506-($-start) dup (0)
dw 0AA55h
;*************************************************************************
KERNEL:
END main ; End of program
和内核
;------------------------------------------------------------
.286 ; CPU type
;------------------------------------------------------------
.model TINY ; memory of model
;---------------------- EXTERNS -----------------------------
;extrn _BootMain:near ; prototype of C func
;------------------------------------------------------------
;------------------------------------------------------------
.code
org 0h ; for Kernel
main:
;----------------------- CODE SEGMENT -----------------------
start:
mov ah,9
mov al,64
mov bh, 0 ; display page 0
mov bl,4
mov cx,1
int 010h
hlt
mov si, OFFSET msgHello
call DisplayMessage
hlt
;*************************************************************************
; PROCEDURE DisplayMessage
; display ASCIIZ string at ds:si via BIOS
;*************************************************************************
DisplayMessage proc near
lodsb ; load next character
or al, al ; test for NUL character
jz DONE
mov ah, 00Eh ; BIOS teletype
mov bh, 000h ; display page 0
mov bl, 007h ; text attribute
int 010h ; invoke BIOS
jmp DisplayMessage
DONE:
ret
DisplayMessage endp
;*************************************************************************
;*******************************************************************************
;messages that needs to be shown
msgHello db 00Dh, 00Ah, "Helloo From the kernel...", 00Dh, 00Ah, 000h
END main ; End of program
有人能帮忙吗?据Michael说,我忘记了小尾端,所以在替换DAPACK中的偏移量和段后,它工作正常。
谢谢大家。我注意到您的代码有几个问题。第一个是次要的。您的引导加载程序以以下内容开始:
start:
cli
mov [BiosDriveID],dl
mov ax,cs ; Setup segment registers
mov ds,ax ; Make DS correct
您可以mov
将引导驱动器号发送到BiosDriveID
。但是,在设置DS
之前,请先执行此操作。当您编写mov[BiosDriveID],dl
时,假定使用DS
段,但您尚未实际设置它。在DS已经有效的情况下,你不能依赖BIOS跳转到你的引导扇区。您应该确保首先设置DS
:
start:
cli
mov ax,cs ; Setup segment registers
mov ds,ax ; Make DS correct
.
.
mov [BiosDriveID],dl ; DS is properly set.
阻止启动内核的主要错误是您读取的磁盘使用了以下数据包:
DAPACK:
db 010h ; Packet Size
db 0 ; Always 0
blkcnt:
dw 1 ; Sectors Count
db_add:
dw 01000h ; Transfer Segment
dw 0h ; Transfer Offset
d_lba:
dd 1 ; Starting LBA (0 - n)
dd 0 ; Bios 48 bit LBA
特别是db\u add
假设保持段:偏移量。您已经这样做了,但是您没有将它们按正确的顺序排列。英特尔x86是小尾端,所以若你们把segment:offset分解成两个单独的字,你们就必须考虑尾端,并把offset放在segment之前。修复是简单的-在结构中交换段和偏移。内容如下:
DAPACK:
db 010h ; Packet Size
db 0 ; Always 0
blkcnt:
dw 1 ; Sectors Count
db_add:
dw 0h ; Transfer Offset \ Reversed to conform
dw 01000h ; Transfer Segment / to little Endian
d_lba:
dd 1 ; Starting LBA (0 - n)
dd 0 ; Bios 48 bit LBA
请给出相应的编译命令。另外,如何在VirtualBox/QEmu/等虚拟机中测试booloader?提供更多详细信息。另外,学习使用调试器并验证您的代码是否已实际加载,然后单步执行。我正在使用virtualbox和物理USB。在
dl
中保存bootdrive之前,我想设置ds
@MichaelPetch:似乎您应该将最后一条注释打包成一个答案,因此,更容易找到问题的答案,因此我们可以投票支持您解决问题:o)