0

私はちょうどマシンレベルの x86 コーディングに近づいているので、私の質問の些細なことを許してください。次のコードは、単純なブートローダーを意図しています。フロッピー ディスクの一部のセクタをメモリにダンプし、ロードされたコードにジャンプします。コメントで説明されているように、ロードされたコードで、メモリ変数から読み取ろうとしましたが、成功しませんでした。

    [ORG 0]

            jmp 07C0h:start     ; Goto segment 07C0

    start:
            ; Update the segment registers
            mov ax, cs
            mov ds, ax
            mov es, ax


    reset:                      ; Reset the floppy drive
            mov ax, 0          
            mov dl, 0          
            int 13h            
            jc reset         


    read:
            mov ax, 1000h       ; ES:BX = 1000:0000
            mov es, ax          
            mov bx, 0           

            mov ah, 2           ; Load disk data to ES:BX
            mov al, 5           ; Load 5 sectors
            mov ch, 0           ; Cylinder=0
            mov cl, 2           ; Sector=2
            mov dh, 0           ; Head=0
            mov dl, 0           ; Drive=0
            int 13h             ; Read!

            jc read             ; on error


            jmp 1000h:0000      ; Jump to the program


    times 510-($-$$) db 0
    dw 0AA55h

       ;     ==  Loaded code from second floppy sector  ==
prog:
        mov     ah,     0x0E       ; Prints a char. This one works: the '-'
        mov     al,     '-'        ;   is printed.
        mov     bx,     0
        int     10h

        mov     bx,     0 
a:                                 
        mov     al,     [L1+bx]    ; Should read from L1 and print out chars.
        inc     bx                 ;   But it prints only white spaces. Why?
        int     10h
        cmp     bx,     10
        jz      h
        jmp a

        cli
        hlt

        L1 db "0123456789"        ; my string

なぜうまくいかないのか理解できません。どんな助けにも感謝します。

4

2 に答える 2

2

上記が単一のアセンブラ ファイルの場合は、 に変更jmp 1000h:0000します。これにより、からずっと累積されjmp 0FE0h:200hたレジスタ オフセットが適切に補正され、制御が物理アドレス に転送されます。ip[ORG 0]0x10000

それに加えて、コードの 2 番目の部分でdsto cs(または to ) を設定します。0FE0h

于 2013-03-29T17:30:50.510 に答える
2

「フロッピーからロード」部分は、ロードされたものとは異なるベース オフセット用にコンパイルされました。そのアドレスを再計算する必要があります。

ジャンプを使用ORG 7C00hして節約することもできます。違いは、セグメントが 07C0h ではなく 0 になることです。

新しいオフセットを [L1-prog] として計算するか、コードを並べ替えることができます。

            jmp 1000h:000Ah      ; Jump to the program
....
L1          db "0123456789"        ; my string
prog:
        mov     ah,     0x0E   

...
        mov     al,     cs:[bx]

テストするアセンブラはありませんが、アイデアはわかります-浮動アドレスの必要性を取り除き、最初に置きます

セグメント 1000H の実際のオフセットは約 32 程度であると大まかに見積もっています。これが、翻訳された L1 のおおよその位置です。代わりに、L1 のコンパイル時間は約 550 と計算されるため、実際には、読み取った 2 番目のセクターから何かをロードしようとしています。2 番目にロードされたセクターの先頭に空白文字またはゼロがありますか?

于 2013-03-29T17:31:49.580 に答える