0

ここ数日、ブートローダーを作成しようとしましたが、これが結果です。

BITS 16


;CONSTANTS
BOOTSEG     equ 07C0h
STACKSEG    equ 1BC0h ; BOOTSEG + 512 Byte (bootloader) + 512 Byte (second stage) + 4096 Byte (buffer) = 1BC0h
STACKSIZE   equ 0400h ; 1KB stack



; INIT
    mov AX, BOOTSEG     
    mov DS, AX      ; set data segment to adress where bootloader will be loaded to
    mov AX, STACKSEG
    cli         ; disable interrupts while set up stack
    mov SS, AX  
    mov SP, STACKSIZE   ; set up stack
    sti         ; restore interrupts
    mov [bootdev], DL   ; save boot device number

;START
    mov SI, string      ; get the adress of the string to print into SI 
    call _printstring

;LOAD 2nd STAGE
    mov AH, 02h     ; int 13h subfunction ah=02
    mov AL, 01h     ; read 1 sector
    mov CX, 02h     ; begin read at track 0, sector 2
    mov DH, 00h     ; head = 0 ????
    mov DL, [bootdev]   ; read from boot device
    mov BX, BOOTSEG     
    add BX, 512
    mov ES, BX      ; write second stage right after first stage
    mov BX, 00h


    int 13h         ; do it
    jc fail
    mov SI, success     ; OK
    call _printstring


    jmp 09C0h:0000h     ; jump to second stage, execute it
                ; does not work:
                    ; 1)    jmp ES:BX
                    ;
                    ; 2)    push ES
                    ;   push BX
                    ;   retf



fail:   
    mov SI,error        ; error on reading second stage
    call _printstring



loop:   
    jmp loop        ; infinite loop at the end


_printhex:
; AX: hex value to print
; Modifies: AX, BX, DX, CX

    mov CX, 4
start:  mov DX, 00h
    mov BX, 10h
    div BX
    cmp DX, 9
    jg letter
    add DL, 30h
    jmp store

letter: add DL, 37h

store:  push DX
    dec CX
    jnz start
    mov CX,4

print:  pop AX
    call _printchar
    dec CX
    jnz print 
    mov AL, 13
    call _printchar
    mov Al, 10
    call _printchar 
    ret






_printchar:
; print char in AL
; Modifies: AX, BX

    mov AH, 0Eh
    mov BX, 07h
    int 10h
    ret




_printstring:
; SI : start adress of string
; Modifies: AX , BX , SI

m1: lodsb           ; Loads [SI] into AL and increases SI by one    
    or AL, AL       ; check if AL = 0
    jz finish       ; then finish
    call _printchar     ; else print charakter
    jmp m1

finish: 
    ret         ; return from the printstring call






;DATA
    string db 'Started my first Bootloader', 13, 10, 0
    success db 'Success', 13, 10, 0
    error db 'Error', 13, 10, 0
    bootdev db 0




; MAKE BOOTSECTOR
    times 510-($-$$) db 0       ; fill up the sector to 512 - 2 = 510 bytes
    dw 0AA55h           ; set the two bootsector identifying bytes





; SECOND STAGE
    add BX, 10
    mov AL, 'A'
    mov AH, 0Eh 
    mov BX, 07h
    int 10h     ; test output

loop2:
    jmp loop2   ; infinite loop at the end

今、私は2つの質問があります:

  1. ES43 行目では、絶対アドレスでジャンプを使用する必要がありますが、との値を使用したいと考えていますBX。そのため、コメントで確認できる 2 つの代替案を試しましたが、うまくいきませんでした。私は何を間違っていますか?

  2. 私は低レベルのプログラミングにまったく慣れていません。私のコードに大きな間違いや小さな間違いはありますか? 考慮しなかったコード スタイル規則はありますか?

コードをフォーマットしたくないので、ここに asm ファイルへのリンクを示します。お気に入りのエディターで読むことができます: https://www.dropbox.com/s/i3jpprf66nlmzz2/mybootloader.asm?m

4

2 に答える 2

6
jmp 09C0h:0000h

push ES
push BX
retf

同様にうまく動作するはずです (もちろん、後者の場合はES=9C0h とBX=0 が提供されます)。

jmp ES:BX有効な命令ではありません。または、少なくとも、期待どおりの結果が得られません。

考えられる問題:

  • 9C0h:0 は間違ったアドレスです
  • 9C0h:0 に期待されるコードがありません (読み取りが失敗したか、読み取りデータを別の場所に保存するよう BIOS に要求しました)。
  • 9C0h:0 のコードは、オフセット 0 で実行を開始するようにコンパイルされていません (x86 マシン コードは通常、位置に依存しないことに注意してください)。
  • おそらくコード/データの破損または初期化されていない変数/レジスタ
于 2013-03-06T13:18:34.373 に答える