2015-12-07 6 views
1

Я создал простой загрузчик со вторым этапом (ядром), загруженным в память, в 0x1000: 0x0000, который мой загрузчик начинает выполнять с jmp 0x1000:0000. Мой загрузчик основан на том, что находится в этом StackOverflow questionprefetch: EIP [00010000]> CS.limit [0000ffff] во время выполнения второй ступени

Мой второй этап/ядро ​​- простая система команд.

Командная система имеет только одну команду, то есть "help" (пока). Все работает отлично, но когда я набираю команду help, я получаю ошибку в Bochs эмулятор:

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

Это код:

[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 

Может кто-нибудь сказать мне, что это значит, и почему его происходит?

+1

Ничего себе, комментариев нет. – Gunner

+1

'com_help' имеет' push bx', но не 'pop bx'. – Jester

+0

Я собираюсь предположить, что это второй этап загрузчика, который вы ранее писали, который был загружен с 0x1000: 0x0000 (и вы далеко подскочили к нему?) –

ответ

2

Этот вопрос кажется тривиальным, как указал Шут. В com_help вы это делаете:

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

вас push BX в стеке, но не восстановить его с pop BX, когда закончите. Это приведет к тому, что команда ret выведет неправильный адрес возврата из стека и продолжит выполнение в ячейку памяти, в которую вы не собираетесь входить. Это может привести к зависанию программы или даже эмулятора, например, BOCHS, чтобы отправить сообщение в зависимости от обстоятельств. Код должен выглядеть так:

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

Я также отметил его как Community Wiki, так как это был комментарий Джесстера, который изначально был правильным. –