Задача такая: в PM (адресатция сегментная), надо вывести строчку на экран. Вроде задача простая, но ничего не получается. Так же я смотрел http://www.wasm.ru/article.php?article=pipm08, почему то тоже строку не выводит. (У меня сделано аналогично). ПОМОГИТЕ ВЧЁМ ОШИБКА ИСХОДНОГО КОДА http://www.wasm.ru/article.php?article=pipm08.
Извеняюсь, проблема не в выводе строки, а в команде Код (Text): lgdt fword ptr GDTR ;здесь происходит RESET ... GDTR dw GDT_size-1 ; 16-битнvй лимит GDT dd ? ; здесь будет 32-битнvй линейнvй адрес GDT На этой команде проц почему то делает RESET! Если знаете в чём проблема поскажите плиз!
Ты уверен, что падение происходит именно там? lgdt команда относительно безобидная. Здесь подобный код пробегал, возможно у тебя аналогичная проблема? Если нет -- приведи весь код.
Я не уверен что здесь, скорее всего где то дальше Привожу: Код (Text): .386p ; разрешить привилегированнvе инструкции i386 ; T++і+=T і+-L (для Real Mode) ; --------------------------------------------------------------------------------------------------------- RM_CODE segment para public 'CODE' use16 assume CS:RM_CODE,SS:RM_STACK @@start: ; очистка экрана: mov AX,3 int 10h in AL,92h or AL,2 out 92h,AL ; вvчисляем линейнvй адрес метки ENTRY_POINT (точка входа в заиеннvй режим): xor EAX,EAX ; обнуляем регистра EAX mov AX,PM_CODE ; AX = номер сегмента PM_CODE shl EAX,4 ; EAX = линейнvй адрес PM_CODE add EAX,offset ENTRY_POINT ; EAX = линейнvй адрес ENTRY_POINT mov dword ptr ENTRY_OFF,EAX ; сохраняем его в переменной ; теперь надо вvчислить линейнvй адрес GDT (для загрузки регистра GDTR): xor EAX,EAX mov AX,RM_CODE ; AX = номер сегмента RM_CODE shl EAX,4 ; EAX = линейнvй адрес RM_CODE add AX,offset GDT ; теперь EAX = линейнvй адрес GDT ; линейнvй адрес GDT кладем в заранее подготовленнуі переменнуі: mov dword ptr GDTR+2,EAX ; собственно, загрузка регистра GDTR: lgdt fword ptr GDTR ; запрет маскируемvх прерvваний: cli ; запрет немаскируемvх прерvваний: in AL,70h or AL,80h out 70h,AL ; переклічение в заиеннvй режим: mov EAX,CR0 or AL,1 mov CR0,EAX ; загрузить новvй селектор в регистр CS db 66h ; префикс изменения разрядности операнда db 0EAh ; опкод командv JMP FAR ENTRY_OFF dd ? ; 32-битное смеение dw 00001000b ; селектор первого дескриптора (CODE_descr) ; TL+TLЈL +T++LT-=-- -+TііLіT+і+T: GDT: ; нулевой дескриптор (обязательно должен присутствовать в GDT!): NULL_descr db 8 dup(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 ; размер GDT GDTR dw GDT_size-1 ; 16-битнvй лимит GDT dd ? ; здесь будет 32-битнvй линейнvй адрес GDT RM_CODE ends ; --------------------------------------------------------------------------------------------------------- ; T++і+=T і+-L (для Protected Mode) ; --------------------------------------------------------------------------------------------------------- PM_CODE segment para public 'CODE' use32 assume CS:PM_CODE, DS:PM_DATA ENTRY_POINT: ; загрузим сегментнvе регистрv селекторами на соответствуіие дескрипторv: mov AX,00010000b ; селектор на второй дескриптор (DATA_descr) mov DS,AX ; в DS его mov AX,00011000b ; селектор на третий дескриптор (VIDEO_descr) mov ES,AX ; а этого в ES xor ESI,ESI ; обнуляем ESI mov SI,PM_DATA ; SI = номер сегмента PM_DATA shl ESI,4 ; ESI = линейнvй адрес сегмента PM_DATA add ESI,offset message ; ESI = линейнvй адрес строки message xor EDI,EDI ; EDI = позиция на экране (относительно 0B8000h) mov ECX,mes_len ; длина текста в ECX ; вvвод на экран: rep movsb ; DS:ESI (наше сообение) -> ES:EDI (видеопамять) jmp $ ; погружаемся в вечнvй цикл PM_CODE ends ; --------------------------------------------------------------------------------------------------------- ; T++і+=T -L==-- (для Protected Mode) ; --------------------------------------------------------------------------------------------------------- PM_DATA segment para public 'DATA' use32 assume CS:PM_DATA ; сообение, которое мv будем вvводить на экран (оформим его в виде блока повторений irpc): message: irpc mes, <Congratulations! We are in PM! Now you MUST Press RESET... > db '&mes&',0Dh endm mes_len equ $-message ; длина в байтах PM_DATA ends ; --------------------------------------------------------------------------------------------------------- ; T++і+=T TT+іL (для Real Mode) ; --------------------------------------------------------------------------------------------------------- RM_STACK segment para stack 'STACK' use16 db 100h dup(?) ; 256 байт под стек - это даже много RM_STACK ends ; --------------------------------------------------------------------------------------------------------- end @@start