Меню сайта

Урок 106. Сегменты

— До сих пор в большинстве примеров программприсутствовал только
— — — один оператор SEGMENT. Так как программныйкод должен находиться в
— — — некотором сегменте, то нужно присвоить емуимя. Учитывая, что
— — — ассемблер должен суметь определить адрессегмента, единственный
— — — оператор ASSUME в прграмме идентифицируеттолько один сегмент
— — — программы. В подобных случаях возможностисегментации программ
— — — микропроцессора 8088 используются неполностью, но часто это и не
— — — нужно. Если программа и ее данныепомещаются в пределах одной и той
— — — же адресуемой области памяти объемом 64кбайт, то нет необходимости
— — — использовать возможности процессора всегментации памяти.

— — — — — Существуют ситуации, когда в программенужно использовать более
— — — одного оператора SEGMENT. Одно из такихприменений рассматривалоясв
— — — гл.5 в нескольких примерах, использующихDOS. В этих примерах в
— — — программе определялся сегмент STACK. Имя,выбранное для сегмента,
— — — несущественно, но его тип, указанный воператоре SEGMENT, должен
— — — быть STACK, так как файлу типа .EXE длявыполнения программы
— — — необходимо отвести стековую область. Еслив программе не задать
— — — сегмент STACK, то загрузчик DOS сохраниторганизацию стека в
— — — некотором месте памяти, которое можетоказаться неприемлемым. В
— — — этом случае программа может работатьнедостаточно хорошо.

— — — — — Другое назначение оператора SEGMENT -расположением данных в
— — — определенном месте памяти. Как известно,при использовании DOS
— — — лучше всего, если программа имеетперемещаемый программный сегмент.
— — — В этом случае нас не заботит, куда DOSзагружает программу. Но в
— — — некоторых случаях фактическое расположениекоманд или данных
— — — оказывается существенным. В этих случаяхдля задания местоположения
— — — данных можно воспользоваться директивой ATоператора SEGMENT.

— — — — — Чтобы понять значение указателя AT,рассмотрим пример. В этом
— — — примере программа использует как Отправнуюточку систему BIOS, хра-
— — — нящаяся в ПЗУ персональной ЭВМ. Хотя языкассемблера является очень
— — — эффективным средством программирования, сдругой стороны это
— — — довольно трудный инструмент, особенно длябольших программ. Поэтому
— — — выбор языка ассемблера обусловливаетсясвойствами, которые делают
— — — его выгодным для решения определеннойзадачи. В случае IBM PC язык
— — — ассемблера — лучший язык дляпрограммирования функций, выполняемых
— — — ROM BIOS. Эти функции можноохарактеризовать как управление устрой-
— — — ствами ввода-вывода, где обычно требуетсяоперировать с отдельными
— — — битами. Программирование подобных задачсводится к возможности ма-
— — — нипулировать содержимым точно заданныхячеек памяти и портов ввода-
— — — вывода. Язык ассемблера также используетсяв тех случаях, когда
— — — необходима минимизация размера программыили максимальное быстро-
— — — действие программы. Всем эти требованияпредъявляет и система ROM
— — — BIOS.
— — — — — В рассматриваемом примере используетсячасть BIOS. В одной из
— — — последующих глав будет рассмотрено, какзаменять части системы
— — — BIOS. Однако в данном случае насинтересует доступ к наборам
— — — данных, которые использует ROM BIOS. Есливы посмотрите
— — — ассемблерный листинг для ROM BIOS (онприводится в приложении A
— — — технического руководства по IBM PC), тоувидите, что сегмент DATA
— — — располагается в сегменте 40H или поабсолютному адресу 400H.
— — — Приведенная на Фиг. 6.12 программаобращается в область данных ПЗУ
— — — системы BIOS c определенной целью. Всегменте DATA имеется
— — — переменная KB_FLAG, которая указываеттекущее состояние
— — — переключателя регистров. Одна из жалоб, частовысказываемых по
— — — поводу клавиатуры IBM, состоит в том, чтонеизвестно, работаете ли
— — — вы в верхнем регистре (CAPS LOCK) или внижнем. Программа на Фиг.
— — — 6.12 считывает значение бита,соответствующего CAPS LOCK, и
— — — изображает его в верхнем правом углуцветного графического дисплея.
— — — Хотя в данной программе это нереализовано, мы будем предполагать,
— — — что при реальном использовании этогофрагмента программы, верхний
&
nbsp- — — правый угол экрана зарезервируется дляописанного индикатора.
— — — — — Сегмент DATA на Фиг. 6.12 показывает, какпрограммист может
— — — передать в программу информацию,расположенную по абсолютным адре-
— — — сам. Оператор DATA SEGMENT используетдирективу AT для того, чтобы
— — — обеспечить безусловную привязку данногосегмента к параграфу 40H.

— — — — — — — — — -Microsoft (R) Macro Assembler Version 5.00 — — — — — — — — — — — — 1/1/80 04:03:25
— — — — — — — — — -Фиг. 6.12 Использование сегментов — — — — — — — — — — — — — — -Page — — — — — — — 1-1

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — PAGE — — -,132
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — TITLE — -Фиг. 6.12 Использование сегментов

— — — — — — — — — — -0000 — — — — — — — — — — — — — — — — -DATA — — -SEGMENT AT 40H
— — — — — — — — — — -0017 — — — — — — — — — — — — — — — — — — — — — — — ORG — — — -17H
— — — — — — — — — — -0017 — ?? — — — — — — — — — — — — -KB_FLAG — — — — — — — — -DB — — — — — ?
— — — — — — — — — — -= 0040 — — — — — — — — — — — — — — — — — — — — — CAPS_STATE — — — — — EQU — — — — 40H
— — — — — — — — — — -0018 — — — — — — — — — — — — — — — — — DATA — — -ENDS

— — — — — — — — — — -0000 — — — — — — — — — — — — — — — — — VIDEO — -SEGMENT AT 0B800H
— — — — — — — — — — -009E — — — — — — — — — — — — — — — — — — — — — — — ORG — — — -158
— — — — — — — — — — -009E — ?? — — — — — — — — — — — — -INDICATOR — — — — — — DB — — — — -?
— — — — — — — — — — -009F — — — — — — — — — — — — — — — — — VIDEO — -ENDS

— — — — — — — — — — -0000 — — — — — — — — — — — — — — — — — CODE — — -SEGMENT
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — ASSUME -CS:CODE

— — — — — — — — — — -0000 — — — — — — — — — — — — — — — — — CAPS — — -PROC — — — FAR
— — — — — — — — — — -0000 — 1E — — — — — — — — — — — — -START: — PUSH — — -DS — — — — — — — — — — — — — — — — — Адрес возврата
— — — — — — — — — — -0001 — B8 0000 — — — — — — — — — — — — — — — — — — — — MOV — — — — AX,0
— — — — — — — — — — -0004 — 50 — — — — — — — — — — — — — — — — — — -PUSH — — — AX
— — — — — — — — — — -0005 — B8 —- R — — — — — — — — — — — — — — — — — — MOV — — — — AX,DATA — — — — — — — — — — — — Адрес сегмента DATA
— — — — — — — — — — -0008 — 8E D8 — — — — — — — — — — — — — — — — — — — — — — MOV — — — — DS,AX
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — ASSUME -DS:DATA
— — — — — — — — — — -000A — B8 —- R — — — — — — — — — — — — — — — — — — MOV — — — — AX,VIDEO — — — — — — — — — — — Адрес сегмента VIDEO
— — — — — — — — — — -000D — 8E C0 — — — — — — — — — — — — — — — — — — — — — — MOV — — — — ES,AX

— — — — — — — — — — — — — — — — — — — — — Фиг. 6.12 Расположение сегмента (начало)
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -ASSUME — ES:VIDEO
— — — — — — — — — — -000F — — — — — — — — — — — — — — — — — DISPLAY_CAPS:
— — — — — — — — — — -000F — B0 18 — — — — — — — — — — — — — — — — — — — — — — MOV — — — — AL,18H — — — — — — — Символ «стрелка вверх» имеет код 18H
— — — — — — — — — — -0011 — F6 06 0017 R 40 — — — — — — — — — — — -TEST — — — KB_FLAG,CAPS_STATE — — — — — Определение состояния клавиши CAPS

— — — — — — — — — -0016 — 75 02 — — — — — — — — — — — — — — — — — — — — — — JNZ — — — — CAPS_LOCK
— — — — — — — — — — -0018 — B0 19 — — — — — — — — — — — — — — — — — — — — — — MOV — — — — AL,19H — — — — — — — Символ «стрелка вниз» имеет код 19H
— — — — — — — — — — -001A — — — — — — — — — — — — — — — — — CAPS_LOCK:
— — — — — — — — — — -001A — 26: A2 009E R — — — — — — — — — — — — — -MOV — — — — INDICATOR,AL — — — Вывод в верхний левый угол экрана
— — — — — — — — — — — 001E — B4 06 — — — — — — — — — — — — — — — — — — — — — — MOV — — — — AH,6 — — — — — — — — — Функция ДОС ввода с клавиатуры
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -и вывода на дисплей
— — — — — — — — — — -0020 — B2 FF — — — — — — — — — — — — — — — — — — — — — — MOV — — — — DL,0FFH — — — — — — -Направление — ввод с клавиатуры
— — — — — — — — — — -0022 — CD 21 — — — — — — — — — — — — — — — — — — — — — — INT — — — — 21H
— — — — — — — — — — -0024 — 3C 00 — — — — — — — — — — — — — — — — — — — — — — CMP — — — — AL,0 — — — — — — — — — Проверка на наличие символа
— — — — — — — — — — -0026 — 74 E7 — — — — — — — — — — — — — — — — — — — — — — JZ — — — — -DISPLAY_CAPS — — — — Нет символа
— — — — — — — — — — -0028 — 3C 25 — — — — — — — — — — — — — — — — — — — — — — CMP — — — — AL,’%’ — — — — — — — — — Проверка на символ конца
— — — — — — — — — — -002A — 74 08 — — — — — — — — — — — — — — — — — — — — — — JE — — — — — RETURN
— — — — — — — — — — -002C — B4 02 — — — — — — — — — — — — — — — — — — — — — — MOV — — — — AH,2 — — — — — — — — — Функция вывода на дисплей
— — — — — — — — — — -002E — 8A D0 — — — — — — — — — — — — — — — — — — — — — — MOV — — — — DL,AL — — — — — — — — Выводимый символ
— — — — — — — — — — -0030 — CD 21 — — — — — — — — — — — — — — — — — — — — — — INT — — — — 21H
— — — — — — — — — — -0032 — EB DB — — — — — — — — — — — — — — — — — — — — — — JMP — — — -DISPLAY_CAPS — — — — Повторение
— — — — — — — — — — -0034 — — — — — — — — — — — — — — — — — RETURN:
— — — — — — — — — — -0034 — CB — — — — — — — — — — — — — — — — — — -RET — — — — — — — — — — — — — Возврат в ДОС
— — — — — — — — — — -0035 — — — — — — — — — — — — — — — — — CAPS — — -ENDP
— — — — — — — — — — -0035 — — — — — — — — — — — — — — — — — CODE — — -ENDS
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — END — — — -START

— — — — — — — — — — — Фиг. 6.12 Расположение сегмента(продолжение)

— — — — — Просматривая листинг ROM BIOS, мынаходим переменную KB_FLAG со
— — — смещением 17H в сегменте DATA. ОператорORG 17H данной программы
— — — задает смещение этой переменной воттранслированной программе.
— — — Наконец, смысл оператора EQU,определяющего константу CAPS_STATE
— — — следует непосредственно из листинга BIOSПЗУ. Заданный этой
— — — константой бит указывает текущее состояниепереключателя CAPS LOCK.

— — — — — В приведенной на Фиг. 6.12 программеимеется еще один оператор
— — — SEGMENT. Он определяет сегмент VIDEO садресом 0B800H. Это
— — — сегментный адрес буфера для адаптерацветного- графического
— — — дисплея. Этот адрес нужен для выводасостояния индикатора на экран
— — — дисплея. Если мы хотим поместить символ вправый верхний угол
— — — экрана, при условии, что строка на экранесодержит 80 символов, то
— — — смещение соответствующей ячейки должнобыть равно 158 в десятичном
— — — представлении. Программируемыехарактерист
ики оборудвания ПК
— — — описываются в гл.8, а пока вы можетепринять сказанное на веру.

— — — — — Первая часть программы устанавливаетнеобходимую адресацию
— — — сегментов. Регистр DS указывает на сегментDATA, а регистр ES — на
— — — сегмент VIDEO. Хотя в программе этисегменты объявлены директивой
— — — AT абсолютными, ассемблер все жеобозначает их значком «R», как
— — — перемещаемые. Программа LINK, тем неменее, подставляет в
— — — соответствующие поля данных правильныезначения.

— — — — — Программа тестирует переменную KB_FLAG, аассемблер в
— — — результате генерирует правильное смещение,равное 17H. В данном
— — — примере символ стрелка вниз используетсядля обозначения обычного
— — — режима, а стрелка вверх обозначает режимCAPS LOCK. Введенные с
— — — клавиатуры символы считываются программойс помощью функции DOS,
— — — выводящей эим символя на дисплей. В данномпримере для выхода из
— — — программы был произвольно выбран символ %.Если пользователь вводит
— — — любой другой символ, то программа выводитего на дисплей и
— — — возвращается к ожиданию ввода следующих.

— — — — — Если ввести и запустить данную программу,то вы увидите в
— — — верхнем правом углу цветного графическогодисплея направленную вниз
— — — или вверх стрелку. Если для цветногодисплея установлен режим 40
— — — символов в строке, при выполнении даннойпрограммы
— — — стрелка-индикатор будет выводиться вовторой сверху строке. Если
— — — нужно использовать эту программу садаптером монохромного дисплея,
— — — то измените адрес сегмента VIDEO на адрес0B000H, соответственно
— — — местоположению буфера монохромногодисплея.

— — — — — При выполнении данной программы садаптером цветного
— — — графического дисплея в режиме 80 символовв строке вы увидите на
— — — экране сильную помеху, «снег».Эта интерференция на экране
— — — происходит из-за прямой передачи данных изпрограммы в буфер
— — — дисплея. В случае монохромного адаптераили цветного-графического
— — — дисплея в режиме 40 символов в строке этойпомехи не будет. О
— — — причинах этого эффекта и о том, как егоизбежать, мы узнаем при
— — — рассмотрении аппаратного обеспечения IBM PC.

— — — — — Существуют и другие применения несколькихоператоров SEGMENT в
— — — одной программе. Если программе требуетсяобласть данных объмом
— — — более 64 кбайт, то она должна организоватьдоступ к этим данным.
— — — Как правило, вы воспользуетесь дляобращения к этой области данных
— — — некоторой схемой управления памятью. Втакой ситуации вам будет
— — — доступна вся эта область данных (заисключением некоторых
— — — фиксированных участков) косвеннуюадресацию.

— — — — — В качестве примера рассмотрим, какинтерпретатор команд DOS
— — — загружает программы. DOS загружаеттранзитную программу на границу
— — — параграфа сразу за резидентной частью DOS.Размер этой резидентной
— — — части может варьироваться в зависимости отчисла дисководов в
— — — системе. Кроме того, этот размер можетсущественно возрастать при
— — — использовании в DOS прерывания INT 27H,которое заканчивает
— — — выполнение программы, но оставляет еерезидентной в памяти. При
— — — этом программный загрузчик DOS долженадресоваться к сегментному
— — — префиксу PSP той программы, которую онзагружает. Проще всего
— — — задать эту структуру данных с помощьюотдельного оператора SEGMENT.

— — — — — На Фиг. 6.13 показано объявление сегмента,которое можно
— — — использовать в двух различных местах. Еслибы можно было посмотреть
— — — текст исходной программы для загрузчикаDOS, то мы бы обнаружили
— — — там подобное объявление. В случаепрограммы, использующей структуру
— — — .EXE, такая сегментация могла быобеспечить доступ к переменным в
— — — сегментном префиксе PSP. В приведенном наФиг. 5.6 примере
— — — программы с применением функций DOS,использовалась структура файла
— — — типа .COM. Это позволяло нам обращаться кразличным ячейкам
— — — сегмента PSP через смещение относительноблока PSP. Задача весьма
— — — облегчалась тем, что DOS загружалапрограмму в тот сегмент, который
— — — содержал PSP.
— — — — — В случае .EXE-файла блок PSP находится нев том же сегменте,
— -&nb
sp- что и команды программы. Так как припередаче управления программе
— — — типа .EXE DOS устанавливает регистры DS иES на сегмент PSP, то
— — — имеет смысл обращаться с PSP как сотдельным сегментом. Приведенный
— — — на Фиг. 6.13 фрагмент программы изсегмента CODE, показывает, как
— — — можно обращаться к данным в блоке PSP.

— — — — — — — — — — — Microsoft (R) Macro AssemblerVersion 5.00 — — — — — — — — — — — — — — 1/1/80 04:03:31
— — — — — — — — — — — Фиг. 6.13 Структура ПрограммногоПрефикса — — — — — — — — — Page — — — — 1-1


— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — PAGE — ,132
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — TITLE Фиг. 6.13 Структура Программного Префикса
— — — — — — — — — — — -0000 — — — — — — — — — — — — — — — — — — PROGRAM_SEGMENT_PREFIX — SEGMENT

— — — — — — — — — — — -0000 — 0002[ — — — — — — — — — — — — — — — — — INT_20 — — — — — — — — — — — DB — — — 2 DUP (?)
— — — — — — — — — — — — — — — — — — — — ??
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — -]

— — — — — — — — — — — -0002 — ???? — — — — — — — — — — — — MEMORY_SIZE DW — — — ?
— — — — — — — — — — — -0004 — 0005[ — — — — — — — — — — — — — — — — — LONG_CALL — — DB — — — 5DUP (?)
— — — — — — — — — — — — — — — — — — — — ??
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — -]

— — — — — — — — — — — -0009 — ???????? — — — — — — — TERMINATE_ADDR — — — DD — — — ?
— — — — — — — — — — — -000D — ???????? — — — — — — — CTRL_BREAK — DD — — — ?
— — — — — — — — — — — -005C — — — — — — — — — — — — — — — — — — — — — — — — ORG — — 05CH
— — — — — — — — — — — -005C — 0010[ — — — — — — — — — — — — — — — — — FCB1 — — — — — — — DB — — — 16 DUP (?)
— — — — — — — — — — — — — — — — — — — — ??
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — -]

— — — — — — — — — — — -006C — — — — — — — — — — — — — — — — — — — — — — — — ORG — — 06CH
— — — — — — — — — — — -006C — 0010[ — — — — — — — — — — — — — — — — — FCB2 — — — — — — — DB — — — 16 DUP (?)
— — — — — — — — — — — — — — — — — — — — ??
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — -]

— — — — — — — — — — — -0080 — — — — — — — — — — — — — — — — — — — — — — — — ORG — — 080H
— — — — — — — — — — — -0080 — 0080[ — — — — — — — — — — — — — — — — — DTA — — — — — — — — DB — — — 128 DUP (?)
— — — — — — — — — — — — — — — — — — — — ??
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — -]


— — — — — — — — — — — -0100 — — — — — — — — — — — — — — — — — — PROGRAM_SEGMENT_PREFIX — ENDS

— — — — — — — — — — — -0000 — — — — — — — — — — — — — — — — — — CODE — SEGMENT
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — ASSUME — — — — — CS:CODE,DS:PROGRAM_SEGMENT_PREFIX

— — — — — — — — — — — -0000 — A1 0002 R — — — — — — — — — — — — — MOV — — AX,MEMORY_SIZE

— — — — — — — — — — — -0003 — — — — — — — — — — — — — — — — — — CODE — ENDS
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — END

— — — — — — — — — — — Фиг. 6.13 Префикс программногосегмента
Продолжение в Комментариях!

Категория: Программирование на Ассемблере | Дата: 20.03.13

Меню раздела
Блок