Сист. прогр. Ч1 (Методические указания к выполнению лабораторных работ по СПО), страница 5
Описание файла
Файл "Сист. прогр. Ч1" внутри архива находится в следующих папках: Методические указания к выполнению лабораторных работ по СПО, сист прогр лабы. Документ из архива "Методические указания к выполнению лабораторных работ по СПО", который расположен в категории "". Всё это находится в предмете "операционные системы" из 7 семестр, которые можно найти в файловом архиве РТУ МИРЭА. Не смотря на прямую связь этого архива с РТУ МИРЭА, его также можно найти и в других разделах. Архив можно найти в разделе "книги и методические указания", в предмете "операционные системы" в общих файлах.
Онлайн просмотр документа "Сист. прогр. Ч1"
Текст 5 страницы из документа "Сист. прогр. Ч1"
Ассоциируя сегменты с сегментными регистрами, ассемблер сможет определить смещения к отдельным областям в каждом сегменте. Например, каждая команда в сегменте кодов имеет определенную длину: первая имеет смещение 0, и если это двухбайтовая команде, вторая команда будет иметь смещение 2 и т.д.
Загрузочному модулю в памяти непосредственно
предшествует 256-байтовая (100Н) область, называемая
префиксом программного сегмента PSP. Программа
загрузчика использует регистр DS для установки адреса
начальной точки PSP. Пользовательская программа должна
сохранить этот адрес, поместив его в стек. Позже команда
RET возьмет этот адрес из стека для возврата в DOS.
В системе требуется, чтобы следующее значение в стеке
являлось нулевым адресом (точнее, смещением). Для этого
команда SUB очищает регистр АХ, вычитая его из этого же
регистра АХ, а команда PUSH заносит это значение в стек.
Загрузчик DOS устанавливает правильные адреса стека в
регистре SS и сегмента кодов в регистре CS. Поскольку
программа загрузчика использует регистр DS для других
целей, необходимо инициализировать регистр DS двумя
командами MOV, как показано на рис.3.1. В следующем
разделе этой главы "Пример исходной программы" детально
поясняется инициализация регистра DS.
Команда RET обеспечивает выход из пользовательской программы и возврат в DOS, используя для этого адрес, записанный в стек в начале программы командой PUSH DS. Другим часто используемым способом завершения программы является команда INT 20H.
CODESG SEGMENT PARA ‘CODE’
BEGIN PRQC FAR
1. ASSUME CS:CODESG,DS:DATASG,SS:STACKG
2. PUSH DS ;3аписать DS в стек
3. SUB AX,AX ;Установить ноль в АХ
PUSH AX ;3аписать ноль в стек
4. MOV AX,DATASG ;3анести адрес
MOV DS,AX ; DATASG в DS
5. RET ;Возврат в DOS
BEGIN ENDP
CODESG ENDS
END BEGIN
Рис.3.1. Инициализация ЕХЕ-программы
Теперь, даже если приведенная инициализация программы до конца не понятна, не отчаивайтесь. Каждая программа фактически имеет аналогичные шаги инициализации, так что их можно дублировать всякий раз при кодировании программ.
ПРИМЕР ИСХОДНОЙ ПРОГРАММЫ
На рис.3.2 обобщены предыдущие сведения в простой исходной программе на ассемблере. Программа содержит сегмент стека -STACKSG и сегмент кода - CODESG.
Сегмент STACKSG содержит один элемент DB (определить байт), который определяет 12 копий слова 'STACKSEG'. В последующих программах стек не определяется таким способом, но при использовании отладчика для просмотра ассемблированной программы на экране данное определение помогает локализовать стек.
Сегмент кода CODESG содержит выполняемые команды программы, хотя первая директива ASSUME не генерирует кода. Директива ASSUME назначает регистр SS для STACKSG и регистр CS для CODESG. В действительности эта директива сообщает ассемблеру, что для адресации в STACKSG необходимо использовать адрес в регистре SS и для адресации в CODESG -адрес в регистре CS. Системный загрузчик при загрузке программы с диска в память для выполнения устанавливает действительные адреса в регистрах SS и CS. Программа не имеет сегмента данных, так как в ней нет определения данных и соответственно в ASSUME нет необходимости ассигновать регистр DS.
page 60,132
TITLE EXASM1 (EXE); Пример регистровых операций
STACKSG SEGMENT PARA STACK 'Stack'
DB 12 DUP('STACKSEG')
STACKSG ENDS
CODESG SEGMENT PARA 'Code'
BEGIN PROC FAR
ASSUME SS:STACKSG, CS:CODESG, DS:NOTHING
PUSH DS ;3аписать DS в стек
SUB AX, AX ;3аписать ноль
PUSH AX ; в стек
MOV AX, 0123H .-Записать 0123 в АХ
ADD AX, 0025H ;Прибавить 25 к АХ
MOV BX,AX ;Переслать АХ в ВХ
ADD BX, AX ;Прибавить ВХ к АХ
MOV CX,BX ; Переслать ВХ в СХ
SUB CX, AX ; Вычесть АХ из СХ
SUB AX, AX ;0чистить АХ
NOP
RET ; Возврат в DOS
BEGIN ENDP ; Конец процедуры
CODESG ENDS ;Конец сегмента
END BEGIN ;Конец программы
Рис.3.2. .Пример исходной программы на ассемблере
АССЕМБЛИРОВАНИЕ И ВЫПОЛНЕНИЕ ПРОГРАММ
Всегда необходимо вводить имя исходного файла и обычно запрашивать OBJ-файл - это требуется для компоновки программы в загрузочный файл. Возможно, потребуется указание LST-файла, особенно, если необходимо проверить сгенерированный машинный код. CRF-файл полезен для очень больших программ, где необходимо видеть, какие команды ссылаются на какие поля данных. Кроме того, ассемблер генерирует в LST-файле номера строк, которые используются в CRF-файле.
Ассемблер преобразует исходные команды в машинный код и выдает на экран сообщения о возможных ошибках. Типичными ошибками являются нарушения ассемблерных соглашений по именам, неправильное написание команд (например, MOVE вместо MOV), а также наличие в операндах неопределенных имен. Программа ASM выдает только коды ошибок, которые объяснены в руководстве по ассемблеру, в то время как программа MASM выдает и коды ошибок, и пояснения к ним. Всего имеется около 100 сообщений об ошибках.
Ассемблер делает попытки скорректировать некоторые ошибки, но в любом случае следует перезагрузить текстовой редактор, исправить исходную программу (EXASM1.ASM) и повторить ассемблирование.
На рис 3.3. показан листинг, полученный в результате ассемблирования программы и записанный на диск под именем EXASM1.LST.
В начале листинга обратите внимание на реакцию ассемблера на директивы PAGE и TITLE. Никакие директивы, включая SEGMENT, PROC, ASSUME и END, не генерируют машинных кодов.
Листинг содержит не только исходный текст, но также в левой части транслированный машинный код в шестнадцатеричном формате. В самой левой колонке находятся шестнадцатеричные адреса команд и данных.
Сегмент стека начинается с относительного адреса 0000. В действительности он загружается в память в соответствии с адресом в регистре SS и нулевым смещением относительно этого адреса. Директива SEGMENT устанавливает 16-кратный адрес и указывает ассемблеру на то, что это начало стека. Сама директива не генерирует машинный код. Команда DB также находится по адресу 0000, содержит 12 копий слова 'STACKSEG'; машинный код представлен значениями 0С (десятичное 12) и шестнадцатеричным представлением ASCII-символов. (В дальнейшем можно использовать отладчик для просмотра результатов в памяти.)
Сегмент стека заканчивается по адресу 0060, что эквивалентно десятичному значению 96 (12x8).
-
Page 60,132
-
TITLE EXASМ1 (EXE) ;Пример регистровых операций
-
; --------------------------------------
-
0000 STACKSG SEGMENT PARA STACK ‘Stack ‘
-
0000 0C [ DB 12 DUP (‘STACKSEG’)
-
53 54 41 43
-
4B 53 45 47
-
]
-
0060 STACKSG ENDS
-
;----------------------------
-
0000 CODESG SEGMENT PARA ‘Code’
-
0000 BEGIN PROC FAR
-
ASSUME SS:STACKSG, CS:CODESG, DS:NOTHING
-
0000 1E PUSH DS ;3аписать DS в стек
-
0001 2B С0 SUB AX, AX ; Записать ноль
-
0003 50 PUSH AX ; в стек
-
0004 B8 0123 MOV AX, 0123H ; Записать шест. 01223 в AX
-
0007 05 0025 ADD AX, 0025H ;Прибавить шест. 25 к AX
-
000А 88 D8 MOV BX, AX
-
0000C 03 D8 ADD BX, AX
-
000E 8B CB MOV CX, BX
-
0010 2B C8 SUB CX,AX
-
0012 2B C0 SUB AX,AX
-
0014 90 NOP
-
0015 CB RET
-
0016 BEGIN ENDP
-
0016 CODESG ENDS
-
END BEGIN ; Конец программы
Segments and Groups:
Name Size Align Combine Class
CODESG ............ 0016 PARA NONE 'CODE'
STACKSG. ........... 0060 PARA STACK 'STACK1
Symbols:
NAME Type Value Attr
Begin F PROC 0000 CODESG Length = 16
Рис.3.3. Листинг ассемблирования программы
Сегмент кода также начинается с относительного адреса 0000: Он загружается в память в соответствии с адресом в регистре CS и нулевым смещением относительно этого адреса. Поскольку ASSUME является директивой ассемблеру, то первая команда, генерирующая машинный код,- это PUSH DS, однобайтовая команда (1E), находящаяся в сегменте на нулевом смещении. Следующая команда SUB АХ,АХ генерирует двухбайтовый машинный код (2В С0), начинающийся с относительного адреса 0001. Пробел между байтами предназначен только для удобства чтения. В данном примере встречаются одно-, двух- и трехбайтовые команды.
Последняя команда END содержит операнд BEGIN, который имеет отношение к имени команды PROC по смещению 0000. Это адрес сегмента кодов, с которого начинается выполнение после загрузки программы.
Листинг ассемблирования программы EXASM1 .LST имеет по директиве PAGE ширину 132 символа и может быть распечатан. Многие принтеры могут печатать текст сжатым шрифтом. Включите ваш принтер и введите команду
MODE LPT1:132,6
Таблица идентификаторов
За листингом ассемблирования программы следует таблица идентификаторов. Первая часть таблицы содержит определенные в программе сегменты и группы вместе с их размерами в байтах, выравниванием и классом. Вторая часть содержит идентификаторы - имена полей данных в сегменте данных (в нашем примере их нет) и метки, назначенные командам в сегменте кодов (одна в нашем примере). Для того, чтобы ассемблер не создавал эту таблицу, следует указать параметр /N вслед за командой MASM, т.е. MASM/N.
Двухпроходный ассемблер
В процессе трансляции исходной программы ассемблер делает два просмотра исходного текста. Одной из основных причин этого являются ссылки вперед. Это происходит в том случае, когда в некоторой команде кодируется метка, значение которой еще не определено ассемблером.
В первом проходе ассемблер просматривает всю исходную программу и строит таблицу идентификаторов, используемых в программе, т.е. имен полей данных и меток программы и их относительных адресов в программе. В первом проходе подсчитывается объем объектного кода, но сам объектный код не генерируется.
Во втором проходе ассемблер использует таблицу идентификаторов, построенную в первом проходе. Так как теперь уже известны длины и относительные адреса всех полей данных и команд, то ассемблер может сгенерировать объектный код для каждой команды. Ассемблер создает, если требуется, файлы: OBJ, LST и CRF.
КОМПОНОВКА ПРОГРАММЫ
Если в результате ассемблирования не обнаружено ошибок, то следующий шаг - компоновка объектного модуля. Файл
EX ASM 1.OBJ содержит только машинный код в шестнадцатеричной форме. Так как программа может загружаться почти в любое место памяти для выполнения, то ассемблер может не определить все машинные адреса. Кроме того, могут использоваться другие (под)программы для объединения с основной. Назначением программы LINK является завершение определения адресных ссылок и объединение (если требуется) нескольких программ.
Для компоновки ассемблированной программы с дискеты вставьте дискету DOS в дисковод А, а дискету с программой - в дисковод В. Пользователи винчестерского диска могут загрузить компоновщик LINK прямо с дисковода С. Введите команду LINK и нажмите клавишу Return. После загрузки в память компоновщик выдает несколько запросов (аналогично MASM), на которые необходимо ответить:
Запрос компоновщика Ответ Действие
Object Modules [.OBJ]: B:EXASM1 Компонует EXASM1.OBJ
Run file [EXASM1.EXE]: В: Создает EXASM1.EXE
List file [NUL.MAP]: CON Создает EXASM1.MAP
Libraries [.LIB]: [Return] По умолчанию
Первый запрос - запрос имен объектных модулей для компоновки, тип OBJ можно опустить.
Второй запрос - запрос имени исполнимого модуля (файла) (по умолчанию A:EXASM1.EXE). Ответ В: требует, чтобы компоновщик создал файл на дисководе В. Практика сохранения одного имени (при разных типах) файла упрощает работу с программами.
Третий запрос предполагает, что LINK выбирает значение по умолчанию - NUL.MAP (т.е. MAP отсутствует). МАР-файл содержит таблицу имен и размеров сегментов и ошибки, которые обнаружит LINK. Типичной ошибкой является неправильное определение сегмента стека. Ответ CON предполагает, что таблица будет выведена на экран вместо записи ее на диск. Это позволяет сэкономить место в дисковой памяти и сразу просмотреть таблицу непосредственно на экране. В нашем примере МАР-файл содержит следующую информацию:
Start Stop Length Name