Главная · Поиск книг · Поступления книг · 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 ... 24 25 26 27 28 29 30  31 32 33 34 35 36 37 ... 198
         16-битовый адрес памяти блока. Сегменты адресуются как параграфы,
         при этом указатель должен быть загружен в один из регистров  сег-
         мента (но не в регистр CS!). Обычно для повторного доступа к бло-
         ку памяти используется либо сегмент данных, либо внешний сегмент.
         Если подпрограмма, которая распределяла память, не является глав-
         ной подпрограммой программы, то старое значение регистра сегмента
         должно  сохраняться и восстанавливаться перед выходом из подпрог-
         раммы.  Кроме того,  перед выходом из подпрограммы распределенная
         память  должна быть возвращена в систему.  Для возврата распреде-
         ленной памяти блока в систему используется функция 49h  MS-DOS  -
         "освободить распределенную память". В листинге 2-11 показано, как
         подпрограмма исполняемой программы .EXE будет  распределять,  ис-
         пользовать  и освобождать память,  используемую как локальную па-
         мять (локальное ЗУ).


          Листинг 2-11. Распределение локальной памяти посредством MS-DOS
         -----------------------------------------------------------------

                     common   SEGMENT ; общие данные, используемые всеми
                     com_1   dw     ?
                     com_2   db     14 DUP (?)
                     common    ENDS
                     dummy_dat  STRUC      ; описание структуры,
                     dummy_1 dw     ?      ; используемой с
                     dummy_2 db     14 DUP (?) ; распределенной памятью
                     dummy_dat ENDS
                             ASSUME ds:common ; доступ к данным COMMON

                                      - 2-38 -
                     local_example  PROC    NEAR ; процедура example
                     push    ds        ; сохранение предыдущего DS
         B8 ---- R   mov     ax,common ; COMMON настраиваемая MS-DOS
                     mov     ds,ax
                     push    es        ; сохранение предыдущего ES
                     mov     ah,048h   ; распределение памяти
                     mov     bx,1      ; запрос 1 блока (16 байт)
                     int     21h       ; вызов MS-DOS
                     jc      not_alloc ; перенос означает сбой распред-я
                     mov     es,ax     ; если распределена, то ее адрес
         ;
         ;                 три примера адресации
         ;
         A1 0000 R   mov     ax,com_1 ; надлежащий сег.-предполагается DS
         B8 0000     mov     ax,dummy_1 ; ошибочный сег.-непосредственный
         26: A1 0000 mov     ax,es:dummy_1 ; надлежащий сег.-замещаемый
                     ;
                     mov     ah,049h   ; освобождение распредел. памяти
                     int     21h       ; вызов MS-DOS
                     jnc     free_ok   ; нет переноса т.е. хорошо
                     not_alloc:
                     ; Сообщение об ошибке, если сбой, распр-я или удал-я
                     free_ok:
                     pop     es        ; восстановление ES
                     pop     ds        ; восстановление DS
                     ret
                     local_example   ENDP  ; конец примера
         -----------------------------------------------------------------

             Листинг 2-11 содержит оба вызова функций MS-DOS "Распределить
         память" и "Освободить память". Вместо регистра DS для указания на
         только что распределенную память,  был использован регистр ES,  а
         регистр  DS зарезервирован для доступа к области общих переменных
         программы.  Заметим, что в отличие от примера стека, для выполне-
         ния доступа к используемой структуре,  определенной здесь, требу-
         ется оператор замещения сегмента (:). Без замещения сегмента инс-
         трукция  mov  ax,dummy_1 не выполняет генерацию ссылки на память,
         используя регистр ES,  но взамен этого генерирует загрузку смеще-
         ния (в нашем случае нуль) в регистр AX.  При добавлении замещения
         сегмента к инструкции mov ax,es:dummy_1 макроассемблер MASM гене-
         рирует  передачу  памяти  из смещения dummy_1 во внешний сегмент.
         Замещение сегмента в листинге 2-11  показано  с  байтом  префикса
         26:.
             При использовании в  программе  нескольких  сегментов  данных
         программист несет ответственность за управление используемыми об-
         ластями данных. Например, если программа X распределяет локальную
         память  и  обновляет  регистр  DS для доступа к этой области,  то
         программист должен помнить о том, что эта область данных по умол-
         чанию  принимается областью данных для всех программ,  вызываемых
         программой X.  Общая область данных,  которая была  определена  в
         программе, доступна еще путем загрузки либо регистра DS, либо ре-
         гистра ES из переменной сегмента,  как показано в  листинге  2-6.
         Программы, изменяющие содержимое своих регистров сегмента, должны
         сохранять и  восстанавливать  первоначальные  значения  регистров
         сегмента для предотвращения своих порождаемых задач от ошибок.
             Всякий раз,  когда в программе используется более одного сег-
         мента данных или внешних сегментов, программист должен быть очень

                                      - 2-39 -
         внимателен к директивам ASSUME (присвоить),  используемым в прог-
         рамме.  При ассемблировании обычных ссылок на память макроассемб-
         лер MASM сначала ищет их таблицу внешних символов для имен  пере-
         менных,   к  которым  осуществляется  доступ.  Если  MASM  найдет
         переменную в таблице символов,  он пытается создать  ссылку,  ис-
         пользуя сегмент,  в котором определена эта переменная.  Если этот
         сегмент отсутствует (т.е. отсутствует соответствующее предложение
         ASSUME), то MASM генерирует сообщение об ошибке "Can't reach with
         segment reg" (нельзя найти регистр сегмента).
             Если MASM не может найти переменную в таблице символов, то он
         предполагает,  что она находится в сегменте данных.  Если  и  это
         предположение  окажется  неудачным,  то  MASM  пытается исправить
         ошибку во время второй передачи путем присоединения  к инструкции
         префикса замещения сегмента.  При неудаче,  получение этого байта
         вызывает другое сообщение об ошибке "Phase error  between passes"
         (ошибка фазы между передачами).
             В случае неудачи или ссылки "вперед", т.е. когда имя перемен-
         ной  еще не находится в таблице символов,  программист должен ис-
         пользовать оператор замещения сегмента (:) для более чистого  оп-
         ределения   макроассемблером  MASM  используемого  сегмента.  Для
         управления доступом в программе также полезен оператор  SEG. Этот
         оператор позволяет программисту получать значение сегмента (базо-
         вый адрес сегмента) для любой  определенной  переменной.  Ссылки,
         создаваемые с помощью предложения SEG, настраиваются MS-DOS и по-
         лезны для создания настраиваемых ссылок вместо абсолютных ссылок.

                       Введение в управление памятью в MS-DOS

             Пример, приведенный в листинге  2-11,  зависит  от  имеющейся
         свободной памяти внутри системы. По умолчанию MS-DOS вырабатывает
         распределение всей памяти для себя при загрузке.  Вызов распреде-
         ления памяти будет неудачным,  т.к. процесс уже имеет всю память,
         даже если он не знает про это. Если программа желает использовать
         функцию распределения памяти,  то некоторая память, полученная во
         время загрузки,  должна быть возвращена в систему. Обычно процесс
         будет  стремиться вернуть всю память ,  которую он не занял прог-
         раммным кодом или буферами.
             Функция, обеспечиваемая  MS-DOS  для обработки возврата части
         распределенной памяти программы в систему,  является функцией 4Ah
         -  "Модификация блока распределенной памяти".  Она позволяет про-
         цессу "вырезать" память из его блока распределения памяти, приня-
         того по умолчанию.
             Заметим, что имеются способы предотвращения процесса от расп-
         ределения всей памяти при загрузке, но их рассмотрение отложим до
         главы 3,  где тема загрузки программ и программных файлов  MS-DOS
         будет обсуждаться более подробно.
             Параметры, требующиеся для функции "Модифицировать блок расп-
         ределения памяти",  это адрес сегмента блока,  который необходимо
         модифицировать, и новый размер блока. Адрес сегмента блока, кото-
         рый содержит программу (размер которой нужно модифицировать), пе-
         редается через PSP (Program Segment Prefix - сегмент программного
         префикса).  PSP является разделом памяти, которым начинается каж-
         дая программа MS-DOS. Подробно содержимое PSP описывается в главе
         3.  Сейчас же для нас важно только то, что адрес сегмента PSP яв-
         ляется адресом сегмента блока, который необходимо модифицировать,
         и нам необходим этот адрес.
             Что касается определения этого параметра, то оно различно для

                                      - 2-40 -
         файлов  типа .COM и файлов типа .EXE. Рис. 2-3 показывает располо-
         жение  памяти для файлов типа .COM и типа .EXE.  PSP является пер-
         вым элементом для каждого типа файлов.  В программе типа .COM  PSP
         содержится в первых 256 байтах программного сегмента и адрес прог-
         раммного сегмента (во всех регистрах  сегмента)  является  адресом
         сегмента PSP.
             Для файлов типа .EXE PSP располагается в его собственном  сег-
         менте. Однако, всякий раз при загрузке программы типа .EXE и полу-
         чении управления от MS-DOS,  оба регистра DS и ES  содержат  адрес
         сегмента PSP.  Таким образом,  для программы любого типа адрес PSP
         можно будет получить, по крайней мере, из регистра DS или регистра
         ES.  Кроме  того,  пользователи MS-DOS версии 3.0 (или выше) могут
         использовать программу получения адреса сегмента программного пре-
         фикса (PSP) - функцию 62h.  MS-DOS возвращает значение адреса сег-
         мента программного префикса в регистре BX.
             Т.к. функция "Модифицировать блок распределенной памяти" пред-
         полагает адрес блока в регистре ES,  то функция может быть вызвана
         непосредственно  при  выполнении запуска программы,  поскольку ре-
         гистр ES уже имеет адрес PSP.

                |\/\/\/\/\/|                         |\/\/\/\/\/|
                |  Память  |                         |  Память  |
                |файла типа|                         |файла типа|
                |   .COM   |                         |   .EXE   |
           0000 |----------|           PSP           |----------|
                |    PSP   |<----------------------->|    PSP   |
           0100 |----------|                         |----------|
                |   Коды   |                         | Сегмент A|
                |    или   |                         |----------|
                |  данные  |                         | Сегмент B|
                |----------|     Конец программы     |----------|
                |   Стек   |<----------------------->| Сегмент C|
           FFFE |----------|                         |----------|
            или | Неисполь-|                         | Неисполь-|
          более |  зуемая  |                         |  зуемая  |
         высокая|  память  |   более высокая память  |  память  |
          память ---------- <-----------------------> ----------

                  Рис.2-3. План памяти программы MS-DOS и сегмента
Предыдущая страница Следующая страница
1 ... 24 25 26 27 28 29 30  31 32 33 34 35 36 37 ... 198
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама