Проблема со стеком в PM

Тема в разделе "WASM.ASSEMBLER", создана пользователем C0DiCK, 18 июн 2006.

  1. C0DiCK

    C0DiCK New Member

    Публикаций:
    0
    Регистрация:
    18 окт 2005
    Сообщения:
    38
    Короче, это опять я.

    Посмотрите пожалуйста на код, отвечающий за инициализацию сегмента стэка и определение регистра ESP. В нём есть ошибка. В коментариях есть предыдущий код. Он хоть и рабочий, но явно с ошибкой. Там было написано:

    MOV AH, Flags1

    TASM подставлял вместо Flags1 значение 5. В результате регистр ESP загружался следующим значением:

    StackBase + StackLimit - 15 + 50000h

    Сразу видно, что это неправильно, но ЭТО РАБОТАЛО. Когда я пытаюсь сделать правильный код, который вы модете увидеть в TMB.asm, компьютер перезагружается, когда программа использует стэк. Кто-нибудь что-нибудь знает?

    [​IMG] _1512437955__tmb.ASM
     
  2. Ole

    Ole Member

    Публикаций:
    0
    Регистрация:
    14 июн 2004
    Сообщения:
    69
    Убери нафиг дескриптор стека из таблицы. Сделай один для IDT, один для кода на всю память, и один для данных на всю память. В SS загрузи дескриптор данных. ESP по желанию. И не парься. Плюсы: меньше фигни - удобство в отладке.

    ЗЫ. Там где кончается физическая память - начинается MMIO, аккуратнее.
     
  3. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Читать про expand down сегменты. Читать, курить, вьезжать. И не использовать их в реальной жизни :) Проблемы, которые они решают, лучше и проще решаются с помощью страниц.



    Хинт: у тебя у сегмента стека тип 0110, а у сегмента данных - 0010. Вот во втором бите собака-то и порылась.
     
  4. C0DiCK

    C0DiCK New Member

    Публикаций:
    0
    Регистрация:
    18 окт 2005
    Сообщения:
    38
    Не въехал. Тип сегмента стека 0110, т.е. для чтения/записи, растёт вниз. ESP указывает почти на конец сегмента. В чём дело то, я этот код сто раз проверял и сверял с учебниками и т.д.?
     
  5. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Неужли так сложно посмотреть документацию? На тему того, что означает "растёт вниз" в данном контексте? Видимо сложно, придётся объяснять.



    Дескриптор сегмента с типом 0110 описывает expand down сегмент данных. Размер этого сегмента, в частности, поле segment limit, трактуется не так как обычно. Для простоты, далее под segment_limit понимается (segment_limit * гранулярность).



    В 16-ти разрядном expand down сегмент (разрядность определяется флагом B/D):


    Код (Text):
    1. base_address + segment_limit - начало
    2. base_address + 0xffff - конец


    В 32-х разрядном expant down сегменте:


    Код (Text):
    1. base_address + segment_limit - начало
    2. base_address + 0xffffffff - конец


    При обращении по смещению меньшему segment_limit, выбрасывается исключение. Идея разработчиков была в том, что ты это исключение можешь обработать и уменьшить segment_limit, сдвинув нижнюю границу сегмента ещё немного вниз. Чтобы сразу не выделять под стек кучу памяти, а делать это потом, когда понадобится. Отличие от нормальных сегментов вызвано тем, что стек растёт вниз, т.е. нужно перемещать именно нижнюю границу.



    Ты ставишь себе ESP меньше чем segment_limit и при первом же обращении к стеку получаешь исключение. Почему же не вызывается твой обработчик исключения? А потому что для вызова обработчика тоже нужен стек, а стека-то и нету. Это называется Double Fault (исключение #DF), но в данном случае даже оно не будет вызвано - сразу машина рестартует.



    А для того чтобы обработать такое исключение, нужно использовать переключение стеков. То есть исключение должно происходить при CPL отличном от CPL обработчика исключения (обычно 3 и 0 соответственно). Если всё это нормльно инициализировать, то при вызове обработчика будет использован другой стек, с которым пока всё впорядке.
     
  6. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Ещё немного подумал... Чтобы получить переключение стеков не обязательно использовать разные CPL, вместо этого можно сделать обработчик исключения отдельной задачей. Вот оказывается зачем такая возможность нужна, как-то раньше не приходило в голову. Надо будет попробовать.
     
  7. C0DiCK

    C0DiCK New Member

    Публикаций:
    0
    Регистрация:
    18 окт 2005
    Сообщения:
    38
    Спасибо, sergh. А насчёт документации - я такой, действительно!!, нигде не видел. Ещё раз - сэнкс.
     
  8. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Если с английским нормально, документацию смотри здесь: http://support.intel.com/design/Pentium4/manuals/253669.htm , PM описан в volume 3.

    Если с английским не очень, то лучше всего там же, просто это будет труднее :)



    Только приготовься - там примерно 800 страниц :)



    Ещё есть мои поделки http://sergh.pisem.net/protected.html , они на русском, короче и понятнее, но не закончено, ещё писать и писать.
     
  9. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Все это очень хорошо описано у Григорьева -- "Микропроцессор i486. Архитектура и программирование."

    Правда, в шестой главе ("Прерывания и ообые случаи") есть очень неприятная ошибка + пара мелких опечаток, но в целом книга очень хорошая. Отчасти и есть перевод документации от Intel.