Assembly 带MASM的2阶段引导加载程序

Assembly 带MASM的2阶段引导加载程序,assembly,x86,kernel,masm,bootloader,Assembly,X86,Kernel,Masm,Bootloader,下面是我的引导扇区和内核代码 我正在使用int 13 func 42将我的引导扇区从usb加载到1000:00(小时) 我跳到内核 但是在加载内核之后总是什么都没有发生 ;------------------------------------------------------------ .286 ; CPU type ;--------------------------------------------------------

下面是我的引导扇区和内核代码 我正在使用int 13 func 42将我的引导扇区从usb加载到1000:00(小时) 我跳到内核 但是在加载内核之后总是什么都没有发生

;------------------------------------------------------------
.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)