i386实模式。关于从内存加载数据的一些问题

时间:2013-03-29 17:19:48

标签: assembly x86 nasm real-mode

我只是接近机器级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

我无法理解为什么它不起作用。我非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

如果以上是单个汇编程序文件,请将jmp 1000h:0000更改为jmp 0FE0h:200h,这将适当地补偿从ip[ORG 0]一直累积的0x10000寄存器偏移量仍然将控制转移到物理地址ds

除此之外,请在代码的第二部分中将cs设置为0FE0h(或{{1}})。

答案 1 :(得分:2)

"从软盘加载" part被编译为与其加载的基本偏移量不同的基本偏移量,您需要重新计算其地址

您也可以使用ORG 7C00h并自己跳转,不同之处在于您的细分将为0而不是07C0h

您可以将新偏移量计算为[L1-prog],也可以重新排序代码:

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

...
        mov     al,     cs:[bx]

我没有一个汇编程序可以测试,但你明白了 - 删除了对浮动地址的需求,把它放在开头

我粗略估计您在1000H段中的实际偏移量大约为32-ish,这是您翻译的L1大致为的位置。相反,你的L1计算编译时间大约是550,所以你实际上试图从你读的第二个扇区加载一些东西。在第二个加载扇区的开头是否有一些空白字符或零?