· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Помогите по защищенному режиму плз!

Посл.отвђт Сообщенiе


Дата: Июл 7, 2004 00:09:14

Если в реальном режиме мы можем пользоваться обычными метками (mov[metka],0) либо вычислять физический адрес (cs shl 4 + metka), то как быть в защищенном режиме использующем всего один дескриптор данных, описывающий сегмент от 0 до 4 Гб. То бишь после переключения в защищенный режим мы погружаемся во мрак. Что использовать в качестве ориентира либо как вычислить адрес? Кто-нибудь знает? Или всё равно придется дополнительным дескриптором описывать область данных!


Дата: Июл 7, 2004 00:50:05

Protopopius
RTFM.


Дата: Июл 7, 2004 00:58:48

Уточняю!
Перешли в защищенный режим и стало быть потеряли содержимое CS, DS и т.д.
Как определить адрес строки, находящейся где-то по середине кода?
Там куда меня послали я не нашел ответа! (RTFM).


Дата: Июл 7, 2004 06:25:17

Protopopius
Вообще то содержимое CS, DS и.т.д не теряется. Если у тебя программа типа COM, то можешь сделать так:
xor eax,eax
mov ebx,eax
mov ax,cs ;можно и mov ax,ds просто я привык CS
shl eax,4
mov bx,your_data
add ebx,eax
...
mov eax,cr0
or al,1
mov cr0,eax
....
....
your_data: db .....
То есть ты в реальном режиме считаешь необходимый адрес, результат будет в регистре EBX. Если остались какие вопросы, то спрашивай.


Дата: Июл 7, 2004 07:44:42 · Поправил: rsrc

Win32: Если посмотреть CS, DS, SS в GDT, то увидишь что у них база 0 предел 4Гб, а это значит, что логический адрес + база (=0) = линейный адрес, дальше идет страничное преобразование. Линейный адрес = эф. смещению, т.е. lea esi, label_next и получаешь адрес. В user-mode адресные простр-ва процессов изолированы.


Дата: Июл 7, 2004 09:30:56

невижу проблем


Дата: Июл 7, 2004 12:38:21 · Поправил: Same

Всё просто
например у тебя есть блок с переменными- этот блок определяеш дескриптором данных -
Помещяеш селектор дескриптора в DS
a потом обращаешся - вычисляя смещение только относительно начала блока данных
например например у тебя дескриптор с данными третий и описывает он участок памяти начинающейся на метке data_block и завершается на метке end_data_block
.radix 16
...
Data_block_Selector = 24d ;Константа
Code_Entry:
;ds = Data_block_Selector
mov ax,Data_block_Selector
mov ds,ax
;dx = com1_base_adrr
mov dx,[0]     ;0  это смещение переменной относительно 
               ;метки начала данных
;dx = com2_base_adrr
mov si,(com2_base_adrr - data_block)
mov dx,ds:[si]     ; это тоже смещение переменной относительно 
                   ;метки начала данных
data_block:
com1_base_adrr dw 03F8
...
...
сom2_base_adrr dw 02F8
...
...
end_data_block:
end Code_Entry

Надеюсь понятно


Дата: Июл 7, 2004 14:56:46

Уточняю!
Имеем дело с сом программой:

org 100h
GDT_adr equ 0x90000 ;64 kb - 8192*8
use16
_start:
; очистка экрана:
mov AX,3
int 10h

; открываем линию А20 (для 32-х битной адресации):
in AL,92h
or AL,2
out 92h,AL

; вычисляем линейный адрес метки ENTRY_POINT (точка входа в защищенный режим):
xor EAX,EAX ; обнуляем регистра EAX
mov AX,cs ; AX = номер сегмента PM_CODE
shl EAX,4 ; EAX = линейный адрес PM_CODE
add EAX,ENTRY_POINT ; EAX = линейный адрес ENTRY_POINT
mov dword[ENTRY_OFF],EAX ; сохраняем его в переменной

; собственно, загрузка регистра GDTR:
lgdt [GDTR]

;устанавливаем дескрипторы
mov ax,GDT_adr shr 4
mov gs,ax
mov ax,0
mov ecx,0
mov ebx,0
call set_descriptor
mov ax,11001111b*256+10011010b ;дескриптор кода системы
mov ebx,0
call set_descriptor
mov ax,11001111b*256+10010010b ;дескриптор данных системы
mov ebx,0
call set_descriptor
mov ax,11001111b*256+10010010b ;дескриптор видеопамяти системы
mov ebx,0x0b8000
call set_descriptor

; запрет маскируемых прерываний:
cli

; запрет немаскируемых прерываний:
in AL,70h
or AL,80h
out 70h,AL

; переключение в защищенный режим:
mov EAX,CR0
or AL,1
mov CR0,EAX

; загрузить новый селектор в регистр CS
db 66h ; префикс изменения разрядности операнда
db 0EAh ; опкод команды JMP FAR
ENTRY_OFF: dd ? ; 32-битное смещение
dw 8 ; селектор первого дескриптора (CODE_descr)

; ТАБЛИЦА ГЛОБАЛЬНЫХ ДЕСКРИПТОРОВ:
GDTR: dw 8191 ; 16-битный лимит GDT
dd GDT_adr ; 32-битный линейный адрес GDT

set_descriptor:
;AH - старшая часть предела и флаги GDXU
;AL - права доступа
;ebx - адрес начала сегмента описываемого данным дескриптором
;eсx - номер дескриптора
mov word[gs:ecx*8],0xFFFF ;мл. часть предела
mov word[gs:ecx*8+2],bx
shr ebx,0x10
mov byte[gs:ecx*8+4],bl ;3-й байт адреса
mov word[gs:ecx*8+5],ax
mov byte[gs:ecx*8+7],bh ;старшая часть адреса
inc ecx
ret


use32
ENTRY_POINT:
;org 0
; загрузим сегментные регистры селекторами на соответствующие дескрипторы:
mov AX,16 ; селектор на второй дескриптор (DATA_descr)
mov DS,AX ; в DS его
mov AX,24
mov ES,AX
mov al,byte[msgg]
mov byte[ds:0x0b8001],al
jmp $ ; погружаемся в вечный цикл

msgg: db '1',84h,'1',84h,'1',84h,'1'

Как после метки ENTRY_POINT вычислить адрес msg, если DS указывает на область от 0 до 4 Гб, а куда нас закинула DOS мы не знаем. Т.е. нам необходимо получить физический адрес msg. При использовании записи lea ebx,[msg] фактически компилятор нам сгенерит 100h + msg, что есть неправильно.


Дата: Июл 8, 2004 11:04:56

Protopopius
Я же тебе ответил. Не пойму что тебе непонятно. Физический адрес в реальном режиме это 16*сегментный регистр+смещение. Так как в защищенном режиме ты не используешь страничное преобразование, то и там этот же адрес будет таким же. Смысл в том что ты в реальном режиме считаешь физический адрес и сохраняешь его например в регистре EBX, а потом в защищенном режиме используешь это значение. Умножение на 16 делается так:
shl eax,4 (смотри мой предыдущий ответ). Ты скажи что тебе непонятно или что тебя не устраивает в таком подходе????

PS: Извини, но похоже ты плохо разбираешься в архитектуре процессоров. Так что почитай книжки и разберись с непонятными тебе вещами. Да, немаскируемые прерывания по моему совсем необязательно запрещать и делать безусловный переход при переходе в защищенный режим тоже необязательно.


Дата: Июл 8, 2004 22:51:11

Same
Шото личность знакомая! ;)


Дата: Июл 9, 2004 09:07:29 · Поправил: Same

2 EvilsInterrupt - На хвост чтоли когда то наступал?:)

2 Protopopius
А если так?
org 100h 
GDT_adr equ 0x90000 ;64 kb - 8192*8 
use16 
_start: 
; очистка экрана: 
mov AX,3 
int 10h 

; открываем линию А20 (для 32-х битной адресации): 
in AL,92h 
or AL,2 
out 92h,AL 

; вычисляем линейный адрес метки ENTRY_POINT (точка входа в защищенный режим): 
xor EAX,EAX ; обнуляем регистра EAX 
mov AX,cs ; AX = номер сегмента PM_CODE 
shl EAX,4 ; EAX = линейный адрес PM_CODE 
add EAX,ENTRY_POINT ; EAX = линейный адрес ENTRY_POINT 
mov dword[ENTRY_OFF],EAX ; сохраняем его в переменной 

; собственно, загрузка регистра GDTR: 
lgdt [GDTR] 

;устанавливаем дескрипторы 
mov ax,GDT_adr shr 4 
mov gs,ax 
mov ax,0 
mov ecx,0 
mov ebx,0 
call set_descriptor 
mov ax,11001111b*256+10011010b ;дескриптор кода системы 
mov ebx,0 
call set_descriptor 
mov ax,11001111b*256+10010010b ;дескриптор данных системы 
mov ebx,0 
call set_descriptor 
mov ax,11001111b*256+10010010b ;дескриптор видеопамяти системы 
mov ebx,0x0b8000 
call set_descriptor 

; запрет маскируемых прерываний: 
cli 

; запрет немаскируемых прерываний: 
in AL,70h 
or AL,80h 
out 70h,AL 

; переключение в защищенный режим: 
mov EAX,CR0 
or AL,1 
mov CR0,EAX 

; загрузить новый селектор в регистр CS 
db 66h ; префикс изменения разрядности операнда 
db 0EAh ; опкод команды JMP FAR 
ENTRY_OFF: dd ? ; 32-битное смещение 
dw 8 ; селектор первого дескриптора (CODE_descr) 

; ТАБЛИЦА ГЛОБАЛЬНЫХ ДЕСКРИПТОРОВ: 
GDTR: dw 8191 ; 16-битный лимит GDT 
dd GDT_adr ; 32-битный линейный адрес GDT 

set_descriptor: 
;AH - старшая часть предела и флаги GDXU 
;AL - права доступа 
;ebx - адрес начала сегмента описываемого данным дескриптором 
;eсx - номер дескриптора 
mov word[gs:ecx*8],0xFFFF ;мл. часть предела 
mov word[gs:ecx*8+2],bx 
shr ebx,0x10 
mov byte[gs:ecx*8+4],bl ;3-й байт адреса 
mov word[gs:ecx*8+5],ax 
mov byte[gs:ecx*8+7],bh ;старшая часть адреса 
inc ecx 
ret 


use32 
ENTRY_POINT: 
;org 0 
; загрузим сегментные регистры селекторами на соответствующие дескрипторы: 
mov BX,16 ; селектор на второй дескриптор (DATA_descr) 
mov AX,DS ;  AX = DS 
xchg AX,BX ;
mov DS,AX
mov AX,24 
mov ES,AX 
mov AX,offset msgg
shl ebx,4 
add EBX,EAX
mov al,[DS:EBX] 
mov byte[ds:0x0b8001],al 
jmp $ ; погружаемся в вечный цикл 

msgg: db '1',84h,'1',84h,'1',84h,'1' 


Дата: Июл 9, 2004 09:14:14

Я думаю перед этим
mov AX,offset msgg
shl ebx,4 
add EBX,EAX
mov al,[DS:EBX] 


написать ещё бы
xor eax,eax


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.204