Pergunta

I'm just approaching to machine-level x86 coding, so please excuse the triviality of my question. The following code is intended to be a simple bootloader. It dumps some sector of floppy disk into memory and then it jumps to loaded code. In the loaded code I was trying to read from a memory variable, without success, as described in comments.

    [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

I can't understand why it doesn't work. I very appreciate any help.

Foi útil?

Solução

The "Loaded from floppy" part was compiled for a different base offset than the one it was loaded into, you need to recalculate its address

You could also use ORG 7C00h and spare yourself the jump, the difference being your segments will be 0 instead of 07C0h

You can either calculate the new offset as [L1-prog] or you can reorder your code:

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

...
        mov     al,     cs:[bx]

I don't have an assembler to test but you get the idea - remove the need for a floating address, put it in the beginning

I roughly estimate your actual offset in segment 1000H to be around 32-ish, that's where your translated L1 will roughly be. Instead your L1 is calculated compile time to be about-ish 550, so you're actually trying to load something from the second sector you read. Do you have some blank characters or zeroes in the beginning of the second loaded sector?

Outras dicas

If the above is a single assembler file, change jmp 1000h:0000 to jmp 0FE0h:200h, this will appropriately compensate for the ip register offset accumulated from all the way from [ORG 0] and still transfer control to physical address 0x10000.

In addition to that, set ds to cs (or to 0FE0h) in the second part of the code.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top