фокусы покусы реального режима - что будет если

Тема в разделе "WASM.ZEN", создана пользователем Rockphorr, 4 мар 2010.

  1. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    l_inc
    Код (Text):
    1. PREFIX_DATA_SIZE    equ 66H
     
  2. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.615
    Адрес:
    Russia
    l_inc
    я бы рассматривал

    Код (Text):
    1. x segment
    2. nop
    3. ....
    4. ;nop ;раскоментирован в первом случае и закоментирован во втором
    5. stosw
    6. mov AX,color*100h+'B'
    7. stosw
    8. ;nop ; раскоментирован во втором при закоментированном первом
    9. mov AX,color*100h+'A'
    10. x ends
    и переходил бы на него так

    mov AX,color*100h+'A'
    jmp ...

    в первом случае я бы припер код нопами к самой границе
    а во втором просто перенес один ноп так чтоб mov оказался брюхом на границе
     
  3. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.615
    Адрес:
    Russia
    хотя пардон, бред так негодиться
     
  4. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.615
    Адрес:
    Russia
    второй случай таким образом не строиться
    надо углядеть код второго mov в отладчике и записывать байтами, во втором случае перенося последний байт mov из конца в начало
     
  5. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    В приведенном мной 16-битном коде (в той части, которая находится под USE16) их нет. Те два префикса внизу — это для возврата по 32-битному адресу.
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    l_inc
    Про это я и говорю. 16x код исполняется в режиме эмуляции. Без префикса - обычный код, с префиксом - усечение регистров.
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    Так нет там префиксов. Например, инструкция xor bx,bx не имеет префикса, хотя регистр и "усечён".
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    l_inc
    Зачем тогда вобще сегмент меняете ?
     
  9. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Rockphorr
    ||
    ||
    ||
    \/
     
  10. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    Для того и меняю, чтобы нормальный 16-битный код исполнялся в 16-битном сегменте без всяких префиксов.
    Хотя это, разумеется, второстепенное. На самом деле менял сегмент (и об этом я пишу уже в третий раз), т.к. ожидал, что при нормальном пробеге по 16-битному сегменту переполнение ip приведёт к переходу потока исполнения к началу сегмента, как это происходит в реальном режиме. Оказалось, что нет. Выборка инструкций даже в 16-битном кодовом сегменте происходит по cs:eip, а не по cs:ip.
    KeSqueer
    А вот мне кажется, что стрелка указывает на мой пост. :)
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    l_inc
    Режим работы процессора определяет как код исполняться будет, а не разрядность кода.)
     
  12. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.615
    Адрес:
    Russia
    KeSqueer
    пардон, ошибся
     
  13. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Clerk
    Довольно спорное утверждение в общем случае. Код есть последовательность байт. Например, код
    26 C7 07 46 75 26 C7 47 02 63 6B
    в 32-битном кодовом сегменте будет исполнятся в соответствии со следующими мнемониками:
    Код (Text):
    1. mov dword [es:edi],0C7267546h
    2. inc edi
    3. add ah, byte[ds:ebx+6Bh]
    А в 16-битном кодовом сегменте этот же код будет исполняться уже так:
    Код (Text):
    1. mov word[es:bx],7546h
    2. mov word[es:bx+2],6B63h
    Хотя применительно к случаю с ip/eip Вы правы... наверное. :)
     
  14. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.615
    Адрес:
    Russia
    меня клерк убеждал что мой проект дос оболочки уг а тут вот такие вопросы возникают
     
  15. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    l_inc
    Спасибо за исследование. Полагаю, такой результат связан с особенности блока выборки и декодирования команд в современных процессорах -- понятное дело, что он кардинально отличается от такового в 8086 и прочих доисторических, с коими я когда-то аналогичные эксперименты проводил. Похоже, что сам IP может благополучно закольцовываться, но выборка команды через границу сегмента оказывается невозможной, т.е. предыдущая команда должна заканчиваться последним байтом сегмента, а следующая -- начинаться с нулевого.

    А в реальном режиме не проверили?
     
  16. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Clerk
    Режим работы определяет размер кода по умолчанию, размер адреса (смещения) по умолчанию и правила дешифровки кодов команд.
     
  17. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    SII
    Так это...
    USE16
    org 7C00h
    ...
    В чём же ещё? :) Только там и закольцовывается. Или имелось в виду не под VMWare? Если да, то на реальной машине лень было проверять.
     
  18. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    l_inc
    Угу, именно не под ВМВаре -- ведь она сама крутится в защищённом режиме, так что кто знает, какие это может вызвать побочные эффекты...
     
  19. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.615
    Адрес:
    Russia
    l_inc
    если в варе в защищенном то может и без вари в защищенном получится с взведенным флагом виртуального8086 ???
     
  20. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    На самом деле нет никакого кольцевания, просто иногда события выглядят как кольцевание.

    Сегментация x86 накладывает ограничение на всё происходящее. В частности, при выполнении кода и выборке команды проверяется лимит кодового сегмента. Если текущая инструкция не умещается в сегменте, проверка лимита проваливается и процессор выбрасывает исключение. Конкретно в этом случае используется вектор #GP = 13 = 0dh.

    Важно понимать, что в реальном режиме, во-первых, существуют 32-битные регистры, в частности, cs:eip, а во-вторых, сегментация никуда не девается - по-другому устроено вычисление базового адреса, но лимиты продолжают функционировать. Все проверки лимитов сегментов происходят и в реальном режиме, и при нарушении также выбрасывается исключение #GP. При инициализации процессора лимиты устанавливаются в 0ffffh, и средствами реального режима их не изменить. Однако существование нереального режима (который представляет из себя реальный с увеличенными до 4G лимитами сегментов данных) доказывает, что (с привлечением других режимов) в принципе установить их можно.

    Что происходило в экспериментах? Заметим, что #GP не перехватывалось, так что используется BIOSовский обработчик, который думает, что пришло IRQ5, возможно, что-то делает с внешним железом (скорее всего, обработка сводится к EOI в контроллер прерываний) и делает iret. Перехват #GP позволяет проверить высказываемые в этом посте утверждения.
    1. Граница сегмента не пересекает инструкции. Последняя инструкция в сегменте выполняется успешно. После чего оказывается eip=10000h, что превосходит лимит. Выбрасывается #GP. В стек помещаются только 16-битные cs:ip. Обработчик через какое-то время делает iret. Поскольку eip было обрезано до 16 бит, то возврат происходит по адресу cs:0. Исполнение продолжается.
    Наблюдаемый эффект: "кольцевание".
    2. Граница сегмента пересекает инструкции. Последняя инструкция в сегменте вызывает #GP. В стек помещаются cs:ip той инструкции, которая вызвала исключение. BIOSовский обработчик через какое-то время делает iret. Процессор возвращается к битой инструкции и, естественно, снова выбрасывает #GP, и получается вечный цикл.
    Наблюдаемый эффект: зависание.

    Бонусная возможность. Загружаем GDT из одного 16-битного селектора кода с лимитом 4G. Выходим в защищённый режим (or cr0,1). Перезагружаем cs в единственный селектор в GDT - обновляется теневая копия в процессоре, включающая, что интересно, лимит кодового сегмента. Возвращаемся в реальный режим (and cr0,not 1), перезагружаем cs нормальным значением для реального режима. Вуаля - реальный режим с отсутствием проверок лимита кодового сегмента. (Собственно, это процедура установки нереального режима с тем отличием, что перезагружается cs вместо ds+es+fs+gs). Теперь никаких #GP нет, а после nop'а по cs:FFFF начинает выполняться инструкция по cs:10000, а не по cs:0, что прямо доказывает отсутствие кольцевания. Естественно, после первого же прерывания старшая половина eip слетит в ноль (мне неизвестно, можно ли намухлевать с флагами разрядности в cs/ss/ещё где-нибудь так, чтобы в стек таки помещался полный eip).

    P.S. На всякий случай проверил на имеющихся под рукой Intel Core2Duo и AMD Turion64 - поведение в обоих случаях такое, как описано.