Page 1 of 1

Posted: Fri Jan 06, 2006 9:34 pm
by DoomEd Archangel
статья http://www.wasm.ru/article.php?article=hardzen
возможно тут есть то что надо:
Алгоритм:
Установить «нереальный режим»
Открыть старшие адресные линии (GateA20)
Установить счетчик в 1048576 (1Mb)
Цикл записи-чтения
Вывести значение счетчика
Закрыть вентиль A20
Выход

Пример листинга:

Code: Select all

.586P

DESCRIPTOR STRUC              ;Структура дескриптора сегмента для 
                                                    ;защищенного режима
 limit   dw 0
 base_1  dw 0
 base_2  db 0
 attr    db 0
 lim_atr db 0
 base_3  db 0
ENDS

GDT segment use16                     ;Таблица GDT
 empty dq 0 
 _code descriptor <0,0,0,0,0,0>   ;Дескриптор для сегмента кода программы
 _temp descriptor <0,0,0,0,0,0>   ;"Нереальный" дескриптор
GDT ends

data segment use16
 gdtr df 0                 ;Поле для регистра GDTR
string db "Memory available: ",20 dup (0)
data ends

stck segment stack use16             ;Стек
 db 256 dup (0)
stck ends

code segment use16
assume cs:code,ss:stck,ds:gdt

start:;entry point
 mov ax,gdt
 mov ds,ax
 mov _code.limit,65535;Лимит сегмента кода 64Кб
 mov eax,code;Получаем физический адрес и загружаем базу
 shl eax,4
 mov _code.base_1,ax
 shr eax,8
 mov _code.base_2,ah
 mov _code.attr,09Ah;Атрибуты - сегмент кода

mov _temp.limit,65535;Устанавливаем лимит в максимальное значение
mov _temp.attr,092h ;Атрибуты - сегмент данных, доступ чтение\запись
mov _temp.lim_atr,08Fh;Устанавливаем старшие биты лимита и бит G

 assume ds:data;Получаем физический адрес таблицы GDT 
 mov ax,data
 mov ds,ax
 mov eax,gdt
 shl eax,4
 mov dword ptr [gdtr+2],eax  ;загружаем лимит и адрес таблицы GDT
 mov word  ptr gdtr,23

 cli;Запрет прерываний 
 mov al,80h;Запрет NMI
 mov dx,70h
 out dx,al
 lgdt gdtr;Загружаем GDTR

 mov eax,cr0;Переключаемся в защищенный режим
 inc al
 mov cr0,eax
 db 0EAh;Дальний JMP для загрузки CS селектором 
 dw offset protect
 dw 08h

 protect:
 mov ax,10h;Загружаем FS в защищенном режиме
 mov fs,ax

 mov eax,cr0;Идем назад в реальный режим
 dec al
 mov cr0,eax
 db 0EAh
 dw offset real
 dw code

 real:;Открываем вентиль GateA20
 mov dx,92h
 in  al,dx
 or  al,2
 out dx,al 

 mov ecx,1048576;Начальное значение счетчика - 1 Мегабайт
 mov al,0AAh;Тестовое значение

 count: 
 mov dl,byte ptr fs:[ecx];Сохраняем старое значение по адресу
 mov byte ptr fs:[ecx],al;пишем туда тестовое
 mov al,byte ptr fs:[ecx];читаем с того же адреса
 mov byte ptr fs:[ecx],dl;востанавливаем старое значение
 cmp al,0AAh;прочитали то что записали?
 jnz exit;Нет - такого адреса физически не существует
 inc ecx;Да - увеличиваем счетчик и повторяем все еще раз
 jmp count

 exit: ;Разрешить прерывания
 mov al,0
 mov dx,70h
 out dx,al
 sti

 mov dx,92h;Закрыть вентиль A20
 in  al,dx
 and al,0FDh
 out dx,al 

 mov ax,cx;процеруда преобразования числа в строку требует
 shr ecx,16;чтобы значение располагалось в DX:AX
 mov dx,cx;Преобразуем DX:AX=ECX
 push ds
 pop  es
 lea di,string
 add di,18;пропускаем строку  "Memory available"
 call DwordToStr;преобразование в символьную форму 

 mov ah,9
 mov dx,offset string;вывод
 int 21h

 mov ax,4c00h;Завершение работы
 int 21h
code ends
end start

Posted: Wed Jan 18, 2006 4:07 pm
by NoName
статья есть редактируем.

Posted: Sat Jan 21, 2006 7:30 pm
by NoName
марио я тебе скинул правленый вариант жду пока поддтвердишь что можно, + какие-нить идеи
Думаю можно включить наш вариант в дистриб, так будет более универсально.

Posted: Sun Jan 22, 2006 1:41 pm
by NoName
v icq link na webfile.ru

Posted: Wed Feb 08, 2006 10:27 pm
by NoName
Mario! Найди нормальный способ записать загрузчик или скажи где там бут сектор и как его через редактор можно зафигачить, тогда я смогу проверить фасмовский код, я знаю где ошибка (в самом компилере!).

Posted: Mon Mar 20, 2006 10:31 pm
by Иван Поддубный
Похоже, что сайт упал

Posted: Mon Mar 20, 2006 10:57 pm
by Serge
lgdt gdtr;Загружаем GDTR

mov eax,cr0;Переключаемся в защищенный режим
inc al
mov cr0,eax
db 0EAh;Дальний JMP для загрузки CS селектором
dw offset protect
dw 08h

protect:
mov ax,10h;Загружаем FS в защищенном режиме
mov fs,ax

mov eax,cr0;Идем назад в реальный режим
dec al
mov cr0,eax
db 0EAh
dw offset real
dw code

real:;Открываем вентиль GateA20
можно проще

...
...
lgdt pword [gdtPtr]
cli
mov eax, cr0
or al, 01b
mov cr0, eax
mov bx, 08
mov fs, bx
and al, 0xFE
mov cr0, eax
sti
...
...

gdt dw 0, 0, 0, 0 ;0
_temp dw 0ffffh,0,0F200h,008fh ;08

gdtPtr dq ?

процессор хранит дескрипторы сегментов в теневых регистрах и не меняет их, пока сегментный регистр не будет перегружен. Поэтому нам не нужен дескриптор для кода и перегружать CS через far JMP тоже не надо. Перешли в PM, загрузили нужный селектор и сразу назад.

Posted: Tue Mar 21, 2006 10:23 pm
by Serge
Mario79

Вот полная заготовка для ДОС
;;;;;;;;;;;;;;;;;;;;;;;
format MZ
heap 0
stack 800h
entry main:start

segment main use16

use16
start:

mov ax,_data
mov ds, ax
mov es, ax

xor eax, eax
mov ax,ds

shl eax, 4

mov bx, gdt
add ebx, eax ; ebx - линейный адрес gdt

mov word [gdtPtr], 2 * 8 -1 ; предел gdt 2 дескриптора = 0x000f
mov dword [gdtPtr + 2], ebx

lgdt pword [gdtPtr]

in al, 0x70 ;запрещаем NMI
mov bl, al
or al, 0x80
out 70h , al
in al, 0x71 ;некоторые RTC после записи байта в порт 0х70
;ожидают обращения к порту 0x71

cli

mov eax, cr0
or al, 01b
mov cr0, eax

mov dx, 0x08
mov gs, dx ;gs - глобальный сегмент с базой 0 и пределом 0xFFFFFFFF

and al, 0xFE
mov cr0, eax

sti

mov al, bl
out 70h , al
in al, 71h

mov dx,92h
in al,dx
or al,2
out dx,al

;теперь можно получить доступ ко всей памяти
;например

mov eax, [gs:0xFFFFFFF0] ;

mov ah,4ch ;завершение ДОС программы
int 21h

segment _data use16

align 16

gdt dw 0, 0, 0, 0 ;0
_flat dw 0ffffh,0,0F200h,008fh ;08 сегмент данных DPL = 3
;база 0, предел 0xFFFFFFFF

gdtPtr dq ?

;;;;;;;;;;;;;;;;;;;;;;;;;;
ДОС и БИОС не испльзуют сегментные регистры gs и fs но EMM386 и QEMM используют
V86 mode и код работать не будет

Posted: Wed Mar 22, 2006 11:16 pm
by Serge
Mario79

Прерывания БИОС могут использовать ES.