Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Различные авторы Весь текст 2311.07 Kb

Программирование и кодирование

Предыдущая страница Следующая страница
1 ... 43 44 45 46 47 48 49  50 51 52 53 54 55 56 ... 198
         ся  частью  большой  темы,  называемой  переключением   контекста
         (context switching).
             Если отобразить сегменты,  в которых  выполняется  программа,
         как ее контекст, то можно увидеть, что при многих обстоятельствах
         бывает необходимо изменять полный контекст  программы.  Примерами
         этого  могут  служить вызовы резидентных подпрограмм,  вызывающих
         библиотеки RTL и использующие некоторые типы оверлеев или сопрог-
         рамм. (Сопрограмма является структурной единицей программы, кото-
         рая используется для описания логически параллельных  действий  и
         вызывается подобно подпрограмме.  В отличие от подпрограммы, каж-
         дый вызов сопрограммы возобновляет ее выполнение с точки  послед-
         него  возврата.  Сопрограмма  представляет собой вид специального
         оверлея, который не имеет связей порождающая-порожденная подпрог-
         раммы).  В этом случае, когда одна подпрограмма получает управле-
         ние,  она желает установить для выполнения свои собственные  сег-
         мент данных,  внешний сегмент и сегмент стека. Во время получения
         управления из другой программы наверняка известно только  то, что
         ее  программный сегмент и указатель инструкции установлены в над-
         лежащие значения.  Обратимся к листингу 3-9. После вызова функции
         загрузки и выполнения программы контекст вызывающей программы был
         сброшен и этот  листинг  показывает  как  устанавливать  контекст
         программы. Пример, приведенный в листинге 3-9, несколько неудачен
         тем, что не сохраняет контекст предыдущей программы, а просто пе-
         резаписывает его.
             При получении управления,  если  необходимо  сохранить целый
         набор регистров, наиболее легким способом выполнения этого явля-
         ется способ, заключающийся в том, чтобы сначала установить новый
         стек программы и затем  записать в него эти регистры.  Поскольку
         значения стекового сегмента и указателя стека не могут быть сох-
         ранены в стеке вызывающей программы  (в связи с отсутствием спо-
         соба получения их обратно) и поскольку  они не могут быть сохра-
         нены в новом стеке (который еще не установлен),  параметры стека
         должны сохраняться в памяти.  Если в виде исключения поместить в
         один и тот же сегмент программные коды и данные, то для сохране-
         ния старых  стекового  сегмента  и  указателя  стека и установке
         новых стекового сегмента и указателя стека может быть  использо-
         вана последовательность программных кодов,  показанная в листин-
         ге 3-11.



                                      - 3-58 -
             Листинг 3-11. Переключение стека для программы типа .EXE
         ----------------------------------------------------------------
         enter:   mov   cs:old_stk_seg,ss  ; Сохранение значений старого
                  mov   cs:old_stk_ptr,sp  ; стека
                  mov   ss,cs:new_stk_seg  ; загрузка значений нового
                  mov   sp,cs:new_stk_ptr  ; стека
                  push  ds        ; регистры стекового сегмента
                  push  es
                  push  ax        ; начало записи в стек общих регистров
                  ...
                  push  bp
                  push  si
                  push  di
                  ...
         body:<тело программы>    ; здесь начинается тело программы
                  ...
                  pop   di        ; начало восстановления общих регистров
                  pop   si
                  pop   bp
                  ...
                  pop   ax
                  pop   es        ; восстановление регистров сегмента
                  mov   ss,cs:old_stk_seg  ; восстановление старых зна-
                  mov   sp,cs:old_stk_ptr  ; чений стека
                  jmp   exit               ; обход памяти данных
         old_stk_seg    dw   ?    ; стековый сегмент вызывающей программы
         old_str_ptr    dw   ?    ; указатель стека вызывающей программы
         ; стековый сегмент подпрограммы
         new_stk_seg    dw   segment stack
         ; указатель стека подпрограммы
         new_stk_ptr    dw   top_of_stack
         exit:                             ; позиция выхода
                  ret             ; возврат в вызывающую программу
         ----------------------------------------------------------------
             Программные коды в листинге 3-11 зависят от имеющихся значе-
         ний для стекового сегмента и указателя стека,  уже размещенных в
         памяти. Для резидентных подпрограмм и подпрограмм RTL это должно
         быть выполнено с помощью процесса инициализации. Надлежащие зна-
         чения в память  для  программ  типа  .EXE  операционная  система
         MS-DOS помещает в процессе настройки.
             В связи с тем, что подпрограммы типа .COM не могут содержать
         значения сегмента,  эти подпрограммы требуют другого способа пе-
         реключения стеков.  Запоминание значений для вершины стека в па-
         мяти не вызывает проблем, за исключением адреса начала сегмента.
         Т.к. подпрограммы типа .COM для своих целей совместно используют
         один и тот же сегмент, то значение стекового сегмента может быть
         получено из регистра  программного сегмента. К несчастью, семей-
         ство микропроцессоров 8086 не поддерживает пересылку из регистра
         сегмента в  регистр сегмента,  поэтому значение может быть пере-
         дано косвенным путем. В связи с отсутствием регистра,  в котором
         можно было бы сохранить значение,  значение передается через па-
         мять,  используя  кодовый  сегмент. Для реализации этого способа
         начинайте подпрограмму со следующей инструкции:

          mov   cs:new_stk_seg,cs   ; получение нового стекового сегмента

             Если необходимо, то для переключения стеков в программе мож-

                                      - 3-59 -
         но разработать два макроса, содержащих требуемые программные ко-
         ды. Первый  макрос  включает  программный  код  из  входа в тело
         программы, а второй макрос программный код  из  выхода  из  тела
         программы. Оба  макроса должны соответствовать именам переменных
         стека в области данных, а второй макрос, кроме того, должен при-
         нимать метку вершины стека top_of_stack как параметр для включе-
         ния в предложение dw для указателя нового стека  new_stk_ptr.  В
         эти макросы  не должна входить инструкция RET.  Это позволит ис-
         пользовать эти макросы для выхода как с помощью инструкций JMP и
         IRET, так и с помощью инструкции RET.
             Для файлов типа .EXE второй макрос  должен  также  принимать
         как параметр имя стекового сегмента.  Пример описанных выше мак-
         росов для файлов типа .COM содержится в листинге  3-12 (INIT28),
         приводимом позднее в этой главе.

                 Дополнительные соображения по переключению стеков

             При переключении стеков, или, наоборот, при манипуляции сте-
         ковым сегментом программа уязвима для прерываний.  При изменении
         стекового сегмента,  но не указателя стека, или, когда возникает
         авария, должно бы произойти прерывание. В семействе микропроцес-
         соров  8086  это предотвращается путем изменения указателя стека
         сразу же после инструкции,  которая загружает стековый  сегмент.
         Когда один из процессоров семейства микропроцессоров 8086 загру-
         жает регистр сегмента (с помощью  инструкции MOV  или инструкции
         POP),  прерывание задерживается до тех пор, пока не будет выпол-
         нена следующая инструкция. Эта особенность позволяет благополуч-
         но обновлять регистр стекового сегмента и регистр указателя сте-
         ка. Это также объясняет то,  почему  отладчик  DEBUG  пропускает
         одну инструкцию  при  отслеживании  инструкции  MOV для регистра
         сегмента. Отладчик DEBUG выполняет программу в  пошаговом режиме
         благодаря установке флажка прерывания, который генерирует преры-
         вание #1,  следующее после большинства инструкций.  Т.к. при вы-
         полнении инструкции,  следующей за инструкцией переслать (MOV) в
         регистр сегмента,  прерывания запрещаются,  то отладчик DEBUG не
         получает управление до тех пор, пока не выполнит две инструкции,
         следующие за инструкцией MOV.
             В некоторых  случаях  не  всегда нужно обращаться к длинному
         переходу  при  переключении стеков,  демонстрируемому в листинге
         3-11. Некоторые  регистры  могут  помещаться  в  стек вызывающей
         программы много раз,  позволяя регистрам использоваться в  прог-
         рамме или,  по крайней мере, передавать новые значения в регистр
         стека. Конкретный программист должен сам решать  вопрос  о  том,
         как много текущего контекста сохранять в отдельной программе.
             Если переключение контекста используется с сопрограммами, то
         каждая подпрограмма  заканчивается  сохранением контекста другой
         подпрограммы. Хотя  это и излишне,  потому что только одной под-
         программе необходимо сохранять контекст другой  подпрограммы, но
         в  действительности  не  вредно.  Сопрограмма,  использующая эту
         структуру,  должна осуществлять выход только через функцию с ко-
         дом 4Ch "Завершить программу" так, чтобы MS-DOS смогла правильно
         завершить программу, независимо от состояния стека.
             Если параметры передаются из одной программы в другую и каж-
         дая программа поддерживает свой собственный стек, то для доступа
         к параметрам в стеке нельзя использовать регистр BP. Вместо это-
         го программисту  необходимо  извлечь значение стекового сегмента
         вызывающей программы и переслать его в любой из  регистров  сег-

                                      - 3-60 -
         мента DS  или  ES и выполнять доступ к памяти относительно этого
         регистра. Параметры затем можно прочитать  из  стека  вызывающей
         программы, даже  если вызываемая программа использует свой собс-
         твенный стек.

                 Введение в резидентную часть оперативной памяти

             В некоторых случаях MS-DOS сама реализуется  как резидентная
         программа. Взгляните снова на рис.3-15, и Вы увидите схему памя-
         ти для типичной MS-DOS версии 2.0 или выше.  (Заметим,  что  это
         исполнение необязательно  применять для версий MS-DOS,  выше чем
         версия 3.1). Все части MS-DOS, за исключением нерезидентной час-
         ти файла  COMMAND.COM,  располагаются  в  оперативной памяти все
         время. Программы пользователя осуществляют доступ к MS-DOS  пос-
         редством прерываний  или  переходов к прерываниям,  точно также,
         как выполнялись резидентные подпрограммы пользователя.
             Отдельные части  операционной  системы  являются  общими для
         всех систем MS-DOS и совместимы даже между  системами  различных
         номеров версий. Другие части систем являются уникальными для от-
         дельных номеров версий или отдельных аппаратных средств, работа-
         ющих под управлением MS-DOS. Различные компоненты. входящие в
         MS-DOS, и  атрибуты,  связанные с каждым компонентом,  показаны в
         таблице 3-6.  Названия компонентов могут изменяться от  версии  к
         версии,  но функции компонентов эквивалентны.  Файлы,  входящие в
         состав того или иного компонента, приведены в Руководстве пользо-
         вателя  для  той или иной версии MS-DOS.  Заметим,  что некоторые
         файлы могут быть "скрытыми" файлами,  которые не высвечиваются  в
Предыдущая страница Следующая страница
1 ... 43 44 45 46 47 48 49  50 51 52 53 54 55 56 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама