assemblynasmx86-16osdevbochs

prefetch: EIP [00010000] > CS.limit [0000ffff] during second stage execution


I have created a simple bootloader with a second stage (kernel) loaded in memory at 0x1000:0x0000 which my bootloader starts executing with jmp 0x1000:0000. My bootloader is based upon the one in this StackOverflow question

My second stage/kernel is a simple command system.

The command system has only one command, i.e "help" (for now). Everything works fine, but when I type the command help, I get the error in Bochs emulator:

[CPU0  ] prefetch: EIP [00010000] > CS.limit [0000ffff]

This is the code:

[BITS 16]
[ORG 0x0000] 

mov ax, cs
mov ds, ax   
xor cx, cx  
mov bx, welcome_msg
call str_prt
call new_line
mov bx, creator_msg
call str_prt
call new_line
mov bx, boot_msg
call str_prt
call new_line
mov bx, [buffer]

mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
mov al, '>'
int 0x10

loop:
in al, 64h  
test al, 1    
je loop
xor ah, ah
int 0x16
call key_scan
jmp loop

key_scan:
cmp al, 0x08
je back_space
cmp al, 0x0d
je enter
cmp cx, 0x0041 
je end
mov ah, 0x0e
int 0x10
mov bx, buffer
add bx, cx
mov [bx], al
inc cx
jmp end
back_space:
cmp cx, 0x00
je end
dec cx
mov ah, 0x0e
mov al, 0x08
int 0x10
mov al, 0x20
int 0x10
mov al, 0x08
int 0x10
jmp end
enter:
xor cx, cx
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
call pro_com
call clear_buffer
mov ah, 0x0e
mov al, '>'
int 0x10
end:
ret

str_prt:
pusha
str:
mov ah, 0x0e
mov al, [bx]
cmp al, '$'
je str_end
int 0x10
add bx, 1
jmp str
str_end:
popa
ret

new_line:
push ax
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
pop ax
ret

clear_buffer:
push ax
push bx
push cx
mov bx, buffer
xor cx, cx
xor ax, ax
start:
cmp cx, 0x41
je end_buff
mov [bx], ax
inc bx
inc cx
jmp start
end_buff:
pop cx
pop bx
pop ax
ret

pro_com:
push bx
push ax
mov bx, buffer
mov al, [bx]
cmp al, 'h'
jne help_end
inc bx
mov al, [bx]
cmp al, 'e'
jne help_end
inc bx
mov al, [bx]
cmp al, 'l'
jne help_end
inc bx
mov al, [bx]
cmp al, 'p'
jne help_end
call com_help
jmp pro_end
help_end:
mov bx, not_found
call str_prt
call new_line
pro_end:
pop ax
pop bx
ret

com_help:
push bx
mov bx, help1_msg
call str_prt
call new_line
ret

buffer times 64 db 0

welcome_msg:
db 'Welcome to myOS$'
creator_msg:
db 'Created by Vishnu Shankar.B$'
boot_msg:
db 'Booting command line interface...$'
not_found:
db 'Command cannot be resolved!$'
help1_msg:
db 'Help not avilable!$'

jmp $
times 4096 - ($ - $$) db 0

Can somebody tell me what this means, and why it is occurring?


Solution

  • The issue seems to be a trivial one as Jester identified. In com_help you do this:

    com_help:
        push bx
        mov bx, help1_msg
        call str_prt
        call new_line
        ret
    

    You push BX on the stack but don't restore it with pop BX when finished. This will cause the ret instruction to pop the wrong return address off the stack and continue execution to a memory location you didn't intend to go to. This can cause a program to hang or even an emulator like BOCHS to throw a message depending on circumstances. The code should look like:

    com_help:
        push bx
        mov bx, help1_msg
        call str_prt
        call new_line
        pop bx
        ret