Hello i'm new here and I hope you can help me :)

I've made a bootloader in assembly that's starting up my kernel. The code for the bootloader looks like this:

; 3.ASM
    ; Load a program off the disk and jump to it

    ; Tell the compiler that this is offset 0.
    ; It isn't offset 0, but it will be after the jump.
    [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           ; Drive=0 (=A)
            int 13h             ;
            jc reset            ; ERROR => reset again


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

            mov ah, 2           ; AH blir 02 (int 13h = read disk sectors into memory)       Load disk data to ES:BX
            mov al, 5           ; Antalet sectorer = 5
            mov ch, 0           ; Cylinder nummer 0
            mov cl, 2           ; Sector nummer 2
            mov dh, 0           ; Head nummer 0
            mov dl, 0           ; Drive nummer 0
            int 13h             ; Read!

            jc read             ; ERROR => Try again


            jmp 1000h:0000      ; Jump to the program


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

(Some of the comments are written in swedish but i'll think you'll understand anyway)

This loads 5 sectors starting at sector 2 of the floppy disk (am I right?).

Then I got my kernel that looks like this:

; AGOS.ASM

            mov ah, 9
            mov al, '='
            mov bx, 7
            mov cx, 10
            int 10h

msg     db "Hello", 00h    ; *, 00h fixar skräpet


       ; Update the segment registers
	    mov si, 0000
            mov ax, cs
            mov ds, ax
            mov es, ax
            mov si, msg     ; msg läggs i si


    print:
            lodsb           ; Al blir memory content på DS:SI. Den tar ett tecken från DS:SI (SI) och lägger i Al och tar sedan bort tecknet från DS:SI

            cmp al, 0       ; CMP jämför om al = 0 (hela strängen på DS:SI är printad) och om den är det
            je done         ; så används kommandot je (Jump if Equal) och hoppar till done (finns äver jne (Jump if Not Equal))

            mov ah, 0Eh     ; Kommando teletype output som skriver ett tecken. (Kommando till int 10h)
            mov bx, 7       ; Färg
            int 10h	    ; Skriver det som står i Al

            jmp print       ; Print next character


; wait for 'any key'

done:   MOV AH,0       
    	INT 16h		; waits for key press
			; AL is ASCII code or zero
			; AH is keyboard code

; store magic value at 0040h:0072h to reboot:
;		0000h - cold boot.
;		1234h - warm boot.
	MOV  AX,0040h
	MOV  DS,AX
	MOV  word[0072h],0000h   ; cold boot.
	JMP  0FFFFh:0000h	 ; reboot!

(Sorry again for the comments in swedish)

And then I got this file:

; include.asm
  ; Disk image

    %include 'AGbootloader.asm'      ;THIS IS THE BOOTLOADER
    %include 'AGOS.asm'                   ;THIS IS THE KERNEL

The last file (include.asm) am I converting to .bin and then i'm using the program "RawWrite" to write it to my formated floppy disk.

The bootloader works perfect and starts the kernel which prints out "==========". But then its supposed to print "Hello" too but it wont.. It just prints the = and then it jumps to 'done' and if I press any button on my keyboard it reboots.

Please, if someone could take a look at this I would be very grateful.

Again: the bootloader seems to be OK but the kernel wont print "hello".

Thanks

Alex

Recommended Answers

All 2 Replies

I should have seen this problem immediately!

You inserted data right in the middle of code thus data now appears to be code to the instruction pointer!
Move it after a RET or JMP, since you set code and data to share the same segment!

int 10h				; VIDEO Interrupt

msg     db "Hello", 00h    ; *, 00h fixar skräpet

       ; Update the segment registers
	    mov si, 0000

What you did is like

Func1:   mov ax,1
         ret

Func2:   mov ax,1
        db 0c3h                   ; opcode for ret

Func1 and Func2 generate exactly the same code!

I should have seen this problem immediately!

You inserted data right in the middle of code thus data now appears to be code to the instruction pointer!
Move it after a RET or JMP, since you set code and data to share the same segment!

int 10h				; VIDEO Interrupt

msg     db "Hello", 00h    ; *, 00h fixar skräpet

       ; Update the segment registers
	    mov si, 0000

What you did is like

Func1:   mov ax,1
         ret

Func2:   mov ax,1
        db 0c3h                   ; opcode for ret

Func1 and Func2 generate exactly the same code!

Ahh thanks you! I'm new to assembly so I didn't new the msg db "hello" couldn't be in the code. I'm used to VB and C# where you put it inside the code ^^.
Thanks again for helping me! I'll mark this as SOLVED now.

Alex

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.