бит направления должен быть установлен для роста вниз в дескрипторе, что для данных имхо лучше не делать.
n0name Этот бит имеет смысл, если используется защита от переполнения стека с помощью предела сегмента. Но в плоской модели сегменты фактически не используются, поэтому на сей бит глубоко плевать. А защита стека осуществляется на уровне страниц (когда при очередном обращении к стеку возникает прерывание по отсутствию страницы (не выгруженности, а именно по отсутствию), ОС либо выделяет стеку ещё одну страницу, либо снимает задачу из-за переполнения стека)
я использую fasm - то что jmp надо это я понимаю - но куда? когда у меня бил дескриптор кода именно - то я делал jmp по pm_entry, но сейчас у меня дескриптор указывает на всю память - тогда наверно нада вычислить физический адрес pm_entry и делать jmp туда - это верно? если да - то как это сделать?
Код (Text): SEG = 0x9000 org 0x7C00 use16 start: ; код boot-сектора (загрузка дополнительных секторов по адресу SEG:0000) jmp far SEG:0 db 0 dup(512 - ($ - start)) org 0 @@: mov ax, SEG mov ds, ax db 0x66 lgdt fword [gdtr - SEG SHL 4] ... db 0x66 db 0xEA dd @F dw CS_SEL org SEG SHL 4 + $ - @B use32 @@: ... gdtr: dw GDT_SIZE - 1 dd gdt gdt: ...
rei3er я говорю, что если дескриптор загрузить с базой 0 - а у тебя дескриптор с физическим адресом cs!!!
rei3er смотри: Код (Text): mov eax, cr0 or al, 1 mov cr0, eax db 0x66 db 0xea dd pm_entry dw full_descr ;jmp fword [code_descr:pme_entry] section pmode use32 pm_entry: вот такой код у меня не работает! Почему? code_descr - это дескриптор, базу которого, нахожу за формулой base = cs*16 и лимитом в размер секции кода full_descr - это дескриптор с базой в 0 и лимитом в 0xffff
SadKo всё норм работает, если вместо full_descr поставить code_descr - но в этом и загвоздка - я, же хочу перейти к флат модели памяти - я думал о варианте что надо вычислить физический адрес pm_entry - но когда пробую - что-то наработает, вот код: Код (Text): mov eax, cr0 or al, 1 mov cr0, eax xor eax, eax mov ax, pmode shl eax, 0x04 add eax, pm_entry mov [pm], eax db 0x66 db 0xea pm dd 0x00 dw full_descr section pmode use32 pm_entry:
Freeman сначала (до перехода) - да Код (Text): full_desc desc_struc 0xffff,0,0,data_acc,0xc0,0 ... struc desc_struc op1,op2,op3,op4,op5,op6 { .limit_l dw op1 .base_l dw op2 .base_m db op3 .access db op4 .lim_h_f db op5 .base_h db op6 } fasm
вот полной код: Код (Text): format MZ heap 0 stack 0x800 entry _code:start include 'pmode.inc' fcode_descr = (fcode_desc-null_desc) fdata_descr = (fdata_desc-null_desc) segment _code use16 start: mov ax, _data mov ds, ax mov ax, 0x03 int 0x10 cli in al, 0x70 or al, 0x80 out 0x70, al in al, 0x92 or al, 0x02 out 0x92, al xor eax, eax mov ax, _gdt shl eax, 0x04 mov [gdtr+0x02], eax lgdt fword [gdtr] mov eax, cr0 or al, 1 mov cr0, eax db 0x66 db 0xea dd pm_entry dw fcode_descr segment pmode use32 pm_entry: mov ax, fdata_descr mov ds, ax mov es, ax jmp $ code_size = ($-pm_entry) segment _data use32 gdtr: dw gdt_size-1 dd 0 segment _gdt use16 gdt: null_desc desc_struc 0,0,0,0,0,0 fcode_desc desc_struc 0xffff,0,0,code_acc,0xc0,0 fdata_desc desc_struc 0xffff,0,0,data_acc,0xc0,0 gdt_size = ($-gdt) может кто-то подскажет, где ошибка?
Freeman я так и думал - но почему-то не работает даже так Код (Text): ... mov ax, _code mov ds, ax xor eax, eax mov ax, pmode shl eax, 0x04 mov [pm], eax db 0x66 ;имхо чтобы сделать jmp fword ... db 0xea pm dd 0x00 dw fcode_descr ...
Freeman а разница? я же создаю новый сегмент pmode, тесть pm_entry = 0 - пробивал ваш вариант - не работает
rei3er Да, от любого неверного указателя она не спасёт. Но точно так же от произвольного неверного указателя не спасёт и лимит, поскольку указатель может указывать на допустимую область памяти, но делать это всё равно неправильно (т.е. обращаться не к той ячейке, которую имел ввиду программист). Ну а от банального переполнения стека из-за, например, зациклившейся рекурсии страничная защита вполне спасает.