возможно тут есть то что надо:
Алгоритм:
Установить «нереальный режим»
Открыть старшие адресные линии (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