Помогите плз разобраться с защищенным режимом... Читаю на сайте статьи Broken Sword`а на эту тему и начал писать код. Но что-то не получается Вот сама программа (на fasm): Код (Text): format binary use16 org 7c00h ;Очистка экрана mov ax, 3 int 10h cli ;Открываем линию A20 для 32-х битной адресации in al, 92h or al, 2 out 92h, al ;Загружаем GDT lgdt [GDTR] ;Переключаемся в защищенный режим mov eax, cr0 or al, 1 mov cr0, eax jmp far 8:entry_point GDT: NULL_descr: times 8 db 0 CODE_descr db 0ffh, 0ffh, 00h, 00h, 00h, 10011010b, 11001111b, 00h DATA_descr db 0ffh, 0ffh, 00h, 00h, 00h, 10010010b, 11001111b, 00h VIDEO_descr db 0ffh, 0ffh, 00h, 80h, 0bh, 10010010b, 01000000b, 00h GDT_size equ $-GDT GDTR: dw GDT_size-1 dd GDT ;-------------------------------------------------------- entry_point: use32 xor eax, eax mov ax, 00010000b mov ds, ax mov ss, ax mov ax, 00011000b mov es, ax mov esi, MSG xor edi, edi mov ecx, 7 rep movsb jmp $ MSG db 'Hello!', 0 Так вот, в чем проблема. До команды jmp far 8:entry_point все идет хорошо. Но вот после нее все падает (т.е. vmware говорит какую-то ошибку про kernel и т.п.). Скажите, что я не так делаю?
Не знаю, что такое "vmware", но эта программа расчитана на запуск из реального режима (дос без расширителей), а директива org 7c00h как бы намекает на то, что ее надо разместить в boot-секторе или хотя бы по адресу <any seg>:<7c00>. Видимо, надо еще почитать рядом в этой статье
VMWare - это эмулятор. То что нужно поместить в бут сектор - это понятно Я записываю образ на дискету и гружу ее эмулятором. Так что тут вроде все в порядке. Да, понял тут вдруг, что строчка не выведется, т.к. сегмент данных другой =) Это я так, к слову.
естественно, читай статью еще раз адрес entry_point должен быть уже отнасительно сегмента, в статье должна быть расчётная формула... попробу сделать так .... jmp far 8:0x10000 org 0x10000 entry_point: use32 ... хотя в маловероятно что сработает
Сам ничего не шарил в PM, почитал cтатьи Broken Sword`а - уже ось свою пишу! Читайте доки - они рулезз!(C) Вот пример: Код (Text): org 0x100 ; Для DOS'a ;org 0x7C00 ; Для BootSector'а ; ; Точка входа (Реальный режим) ; start: ; ; Включить линию A20 ; in al,0x92 or al,2 out 0x92,al ; ; Вычислить линейный адресс метки pm_start ; xor eax,eax mov ax,cs shl eax,4 add eax,pm_start mov [ENTRY_OFF],eax ; ; Вычислить линейный адресс pm_start ; xor eax,eax mov ax,cs shl eax,4 add ax,GDT ; ; Загрузить GDT ; mov dword [GDTR+2],eax lgdt fword [GDTR] ; ; Запретить все прерывания (включая NMI) ; cli in al,0x70 or al,0x80 out 0x70,al ; ; Перейти в защищённый режим ; mov eax,cr0 or al,1 mov cr0,eax ; ; Опкод инструкции jmp (это необходимо для загрузки секлектора кода в регистр CS) ; db 66h ; префикс - изменение разрядности кода (0x66 - 32 бита) db 0EAh ; опкод jmp ENTRY_OFF dd ? ; куда прыгать? dw 00001000b ; селектор ; ; Мы в защищённом режиме :) ; use32 pm_start: ; ; Загрузим селектор (2й сегмент в таблице - данные) в сегментные регистры ; mov ax,16 mov ds,ax mov es,ax mov fs,ax mov gs,ax mov ss,ax mov ss,ax ; ; Установим стек ; mov esp,STACK_TOP ; ; Вешаемся :) ; hlt ; ; данные ; GDT: NULL_descr db 000h,000h,00h,00h,00h,00000000b,00000000b,00h CODE_descr db 0FFh,0FFh,00h,00h,00h,10011010b,11001111b,00h DATA_descr db 0FFh,0FFh,00h,00h,00h,10010010b,11001111b,00h GDT_size equ $-GDT GDTR dw GDT_size-1 dd ? ; ; Вершина стека - 4Мб ; STACK_TOP = 1024*1024*4
В общем все дело было в эмуляторе оказывается... Он видно не очень хорошо работает =) Спасибо всем ответившим. XDEV86 Вот хотел как раз по этому поводу спросить. В статье дается программа - как я понял чистый exe`шник. С сегментами там и т.п. Вот только чего не пойму - это каким образом предполагается его (по сути выполняемый файл) записывать в бут сектор? Объясните дураку...
А мне за это еще и платят Забудь про exe ! пиши через комы сам (сам ! )) ) BS (Back Space ?) уже "осознал"... теперь тока так и пишет... Кидаю старые куски сорцов моей оси... (так куча всякой батвы, включая загрузку PE, работу с Fat32 и удаленную отладку через GNU Debug) но там конченный стиль написания кое-где (отголоски предидущих версий и пр.) Ща, я ее переписываю, бо эта тупая версия, но для начала сойдет... П.С. Кто бы сказал как внутри обработчика прерывания узнать его номер ? А то приходится ради вывода циферок с номером исключения описывать отдельные обработчики ? Наверняка есть какой-то бит порта контроллера интерраптов ? че-то не могу найти...