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

 WASM Phorum —› WASM.ASSEMBLER —› DOS & real mode & линейная адресация

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


Дата: Июл 20, 2004 19:58:26

Здравствуйте, уважаемые

Появилась проблемка - может кто-нибудь знает ее решение:
Есть такая книжечка Программирование на аппаратном уровне. В. Кулаков

Так вот, там есть пример линейной адресации (использование ОП до 4 Гб)
Initialization proc NEAR
        pushad
        mov     [CS:Save_SP],SP
        mov     AX,SS
        mov     [CS:Save_SS],AX
        mov     AX,DS
        mov     [CS:Save_DS],AX
        mov     AX,CS
        mov     [word ptr CS:Self_Mod_CS],AX
        mov     DS,AX
        cli
        mov     SS,AX
        mov     SP,offset Local_Stk_Top
        sti

        call    SetLAddrModeForGS

        cli
        mov     SP,[CS:Save_SP]
        mov     AX,[CS:Save_SS]
        mov     SS,AX
        mov     AX,[CS:Save_DS]
        mov     DS,AX
        sti
        call    Enable_A20
        popad
        ret
Initialization endp

Save_SP DW ?
Save_SS DW ?
Save_DS DW ?
GDTPtr  DQ ?
GDT DW 00000h,00000h,00000h,00000h ;не используется
    DW 0FFFFh,00000h,09A00h,00000h ;сегмент кода CS
    DW 0FFFFh,00000h,09200h,00000h ;сегмент данных DS
    DW 0FFFFh,00000h,09200h,0008Fh ;сегмент GS
label GDTEnd word
        DB 255 DUP(0FFh)
Local_Stk_Top DB (0FFh)

SetLAddrModeForGS proc near
        mov     AX,CS
        movzx   EAX,AX
        shl     EAX,4   ;умножить номер параграфа на 16
        mov     EBX,EAX ;сохранить линейный адрес в EBX
        mov     [word ptr CS:GDT+10],AX
        mov     [word ptr CS:GDT+18],AX
        ror     EAX,16
        mov     [byte ptr CS:GDT+12],AL
        mov     [byte ptr CS:GDT+20],AL
        add     EBX, offset GDT
        mov [word ptr CS:GDTPtr],(offset GDTEnd-GDT-1)
        mov     [dword ptr CS:GDTPtr+2],EBX
        pushf
        cli
        in      AL,CMOS_ADDR
        mov     AH,AL
        or      AL,080h      ;установить старший разряд
        out     CMOS_ADDR,AL ;не затрагивая остальные
        and     AH,080h
        mov     CH,AH
        lgdt    [fword ptr CS:GDTPtr]
        mov     BX,CS    ;запомнить сегмент кода
        mov     EAX,CR0
        or      AL,01b   ;установить бит PE
        mov     CR0,EAX  ;защита разрешена
                DB      0EAh
                DW      (offset SetPMode)
                DW      SYS_PROT_CS
SetPMode:
        mov     AX,SYS_REAL_SEG
        mov     SS,AX
        mov     DS,AX
        mov     ES,AX
        mov     FS,AX
        mov     AX,SYS_MONDO_SEG
        mov     GS,AX
        mov     EAX,CR0
        and     AL,11111110b ;сбросить бит PE
        mov     CR0,EAX      ;защита отключена

            DB 0EAh
            DW (offset SetRMode)
Self_Mod_CS DW ?

SetRMode:
        mov     SS,BX
        mov     DS,BX
        xor     AX,AX
        mov     ES,AX
        mov     FS,AX
        in      AL,CMOS_ADDR
        and     AL,07Fh
        or      AL,CH
        out     CMOS_ADDR,AL
        popf
        ret
SetLAddrModeForGS endp

Enable_A20 proc near
        call    Wait8042BufferEmpty
        mov     AL,0D1h ;команда управления линий A20
        out     64h,AL
        call    Wait8042BufferEmpty
        mov     AL,0DFh ;разрешить работу линии
        out     60h,AL
        call    Wait8042BufferEmpty
        ret
Enable_A20 endp

Wait8042BufferEmpty proc near
        push    CX
        mov     CX,0FFFFh  ;задать число циклов
@@kb:   in      AL,64h     ;получить статус
        test    AL,10b     ;буфер i8042 свободен?
        loopnz  @@kb       ;если нет, то цикл
        pop     CX
        ret
Wait8042BufferEmpty endp

После пытаюсь сделать нечто похожее на это:
        mov     EBX,200000h
        mov     ECX,100000h/4
        xor     EAX,EAX
@@ClearMemory:
        mov     GS:[EBX],EAX
        add     EBX,4
        dec     ECX
        jnz     @@ClearMemory

и тут происходит такая фигня -
прога типа подвисает,
когда смотрю ее в td - на этой строчке останавливается и ничего н происходит - но можно остановить нажав на Ctrl+Break - т.е. я так понимаю в режиме трассировки прога не зависает.

Когда снижаю адрес "смещение" в ebx ниже 0FFFFh - все норм (пока не дойдет выше этого предела), т.е. есть предположения что режим линейной адресации не включен, хотя под конец уже брал процедуру из примеров и вставлял себе в прогу - хрен!
Да еще проблемка, в книжке написаны примеры под режим IDEAL для TASM а я пишу под режим MASM в TASM`е, и приходится синтаксис некотрый менять, например
mov [GS:EBX], EAX 
я поменял
на
mov GS:[EBX], EAX
думаю это одно и тоже - хотя кто знает, порой когда долго не получается уже начинаешь думать не плепить ли лишний пробел или написать другим регистром :) Просто уже не знаю что делать, смотрел и результаты CR0, GS - вроде все как и должно быть для линейной адресации.
Да и примеры из книги - работают нормально (уже скомпиллированные)

Все лишние драйверы и менеджеры памяти не грузятся (отключены). Грузятся только драва от клавы (и то иногда отключал). OS - MsDos 6.22.

Люди добрые, помогите. В чем может быть дело (понимаю что в руках, но хотелось бы узнать в каком именно месте и попытаться исправить :) ) ?


Дата: Июл 21, 2004 09:54:14

в отладчиках реального режима, а тем более в TD, такие вещи не проверяются - попробуй без отладчиков что-то типа переключения в текстовый режим и записи по адресу GS:0B8000 (видеопамять) - если увидишь на экране свои каракули, значит все работает.

а насчет отладчиков - они перед загрузкой проги, возможно, перезагружаеют все сегментные регистры новыми значениями, поэтому GS порится


Дата: Июл 21, 2004 14:55:45

"они перед загрузкой проги, возможно, перезагружаеют все сегментные регистры новыми значениями, поэтому GS порится"

Ответ неверный :) При изменении сегментного регистра в (не)реальном режиме изменяется только база, но не лимит. Просто если в защищенном режиме сегментные регистры изменялись, то после возвращения в (не)реальный режим их необходимо перезагрузить. В данном случае необходимо обнулить GS (а остальные вообще не трогать ни в защищенном, ни в "нереальном" режимах).

P. S. Кстати, зачем ограничиваться одним "нереальным" сегментным регистром? Можно загрузить все регистры (кроме CS, ибо бессмысленно).


Дата: Июл 21, 2004 18:42:17

>>При изменении сегментного регистра в (не)реальном режиме изменяется только база, но не лимит.

я тоже помню - это из Зубкова. Но Кулаков (откуда взят данный исходник) кричит, что GS трогать в реальном режиме нельзя. Вот цитата (дословно):

...
ВНИМАНИЕ:
Как уже было указано выше, после выхода из защищенного режима нельзя перезаписывать регистр GS, иначе будет полностью или частично стерта информация в соотв. теневом регистре. В частности, нельзя выполнять операции сохранения/восстановления содержимого регистра при помощи команд работы со стеком push и pop...
...

Т.к. сам я не пробовал, а у человека не работает, то скорее всего, прав Кулаков, т.е. теневой регистр стирается не только частично, но и полностью )

а т.к. данная фигня вообще недокументирована, то и соответственно самым вероятным будет такой итог: на некоторых моделях x86 меняется только база (такой экземпляр попался Зубкову), а на некоторых (более "правильных") - и лимит тоже.

насчет твоего "обнуления" - это зачем? там базы и так в нулях все.


Дата: Июл 21, 2004 21:25:33

Broken Sword
не важно, что я туда записываю, обнуляю или что то еще - важен сам факт записи и считывания.

Про TD это понятно, я его как вариант описал - в нем то ессно не работает, да и просто так тож не работало


А дело было походу вот в чем - надо было писать в режиме IDEAL, а я все переделывал в MASM, не разбирался пока почему из-за этого не работает...

ВОбщем кому интересно могу дать исходники включения линейной адресации (доступ к ОП выше 1 мб, до 4 Гб)
Позже разберусь с режимами IDEAL (походу для защищенного режима) и MASM, и может расскажу, в чем дело.

А так спасибо вам, за то что откликнрулись, правда не ждал, что будет так много сообщений, которые написаны - лишь бы отписаться....


Дата: Июл 21, 2004 22:43:10

2 Broken Sword

У меня (Athlon XP) все работает так, как у Зубкова (если, конечно, опечатки исправить :)

2IgYek

Э-э-э... Я не совсем понял - программа у тебя заработала или нет? И если да, то что ты с ней сделал?


Дата: Июл 22, 2004 12:50:25 · Поправил: Same

Есть много глупых моментов - если нужно поставить Unreal mode - и в GS загнать дескриптор описывающий всю память - то это можно сделать проще...

P.S
Enable_A20 proc near
        call    Wait8042BufferEmpty
        mov     AL,0D1h ;команда управления линий A20
        out     64h,AL
        call    Wait8042BufferEmpty
        mov     AL,0DFh ;разрешить работу линии
        out     60h,AL
        call    Wait8042BufferEmpty
        ret
Enable_A20 endp

Wait8042BufferEmpty proc near
        push    CX
        mov     CX,0FFFFh  ;задать число циклов
@@kb:   in      AL,64h     ;получить статус
        test    AL,10b     ;буфер i8042 свободен?
        loopnz  @@kb       ;если нет, то цикл
        pop     CX
        ret
Wait8042BufferEmpty endp

Много места для кода - лучше так
Enable_A20:;push ax ;исли нужно сохранить значение AX
                    ;то это и в конце мона раскоментировать
            in al,92h ;См.-  http://wasm.ru/forum/files/_625753930__ports.zip

            or al,02h ;Бит 1(счет с нулевого) - Индикатор линии A 20
            out 92h,al
           ;pop ax
           ret


Дата: Июл 22, 2004 20:02:50

ava
да, заработало. Я просто переписал свой код, то есть написал так же как в книжке - и все заработало.
Из этого я сделал вывод - что не надо было мне переделывать из стиля IDEAL в стиль MASM (директива компилятора, в самом начале сурсика пишется)

Same
Спасибо за сокращение. За ссылку - еще больше спасиб :*) (первый раз такую инфу вижу)

Кому интересен код - выкладываю в виде файлика (сжато правда в линухе :) но ЗИП это открывает)
Этот модуль прилеплять в программку с виде
IDEAL	; вот из-за этой байды не работало
LOCALS
model small ; или что хотите

include "mem.inc"

CODESEG
;  все ваши дела
ENDS


вот

_1962700525__mem.inc.bz2


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