Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | ||
|
Объектный код, т. е. результат трансляции С0-программы, представляет собой программу на языке ассемблера IBM PC, состоящую из сегмента кода (команд), сегмента данных и сегмента стека. Сегмент данных содержит области для хранения значений глобальных переменных С0-программы, создаваемые псевдокомандами вида:
_имя DW?
Локальные переменные и параметры каждой функции С0-программы хранятся в сегменте стека в виде кадра, структура которого показана на рис. 1. Адрес кадра находится в регистре ВР. На рис. 2 показан кадр стека функции kod.
В отличие от глобальных переменных, адреса которых в ассемблерной программе задаются их именами, адреса локальных переменных задаются с помощью смещений относительно регистра ВР в виде:
смещeние [BP].
В этом случае в объектной программе "Коды символов" адресом переменной с является ее имя, а адрес переменной (параметра) x запишется как 6[ВР].
Сегмент команд состоит из процедур на языке ассемблера. Каждая процедура соответствует одной функции С0-программы и имеет такое же имя (перед ним вставляется подчеркивание). Процедуры размещены в таком же порядке, как функции С0-программы.
Локальная переменная k
-4 ...
-2 Локальная переменная 1
BP Адрес предыдущего кадра -2 Значение y
2 Адрес возврата BP 0 Адрес предыд. кадра
4 Параметр n 2 Адрес возврата
... 4 Значение baza
Параметр 1 6 Значение x
Рис. 1. Кадр стека Рис. 2. Кадр стека
функции kod
Пример 2. Структура объектной программы для примера 1:
ASSUME CS:KOM_,SS:STEK_,DS:DAN_
; Сегмент стека
STEK_ SEGMENT STACK
DW 10000 DUP (?); Область памяти для стека
DNOST_ DW?
STEK_ ENDS
; Сегмент команд
KOM_ SEGMENT
_kod PROC;
...; Объектный код функции kod
_kod ENDP;
_main PROC;
...; Объектный код функции main
_main ENDP;
INCLUDE std.asm; Процедуры библиотечных функций
KOM_ ENDS
; Сегмент данных
DAN_ SEGMENT
_c DW?;Область для значения глобальной переменной c
DAN_ ENDS
END _main; Адрес точки входа в программу
;Компилятоp С0 от 10/04/08;
;колич. ошибок 0
Структура обычной процедуры (не main):
_имя PROC
; Пролог процедуры (создание кадра стека)
PUSH BP; Сохранение регистра BP
MOV BP,SP; Адрес кадра стека
[ SUB SP,2*кол.лок.переменных;Создание лок-х пер-х]
; Объектный код операторов функции
...
; Объектный код оператора return; обычной функции (не main)
[ ADD SP,2*кол.лок.перем-х;Удаление локальных пер-х ]
POP BP; Восстановление регистра BP
RET 2*кол.параметров;Удаление параметров и возврат
_имя ENDP
Команда PUSH сохраняет значение регистра BP в стеке, MOV пересылает адрес кадра стека в регистр BP, SUB выделяет в кадре стека место для локальных переменных.
Команда ADD удаляет из стека локальные переменные, РОР восстанавливает в регистре BP адрес кадра вызывающей функции, RET удаляет из стека параметры функции и выполняет возврат.
Для функции main вместо команды RET используются команды:
MOV AH,4CH
INT 21H
Они обеспечивает выход в операционную систему с помощью функции 4СН прерывания номер 21H (типа 21Н).
Процедура main имеет такой же пролог, как и обычная процедура, но предварительно должна инициализировать регистры сегментов и указатель стека.
Структура процедуры main:
_main PROC FAR
MOV AX,DAN_;Адрес сегмента данных--> регистр DS
MOV DS,AX;
MOV AX,STEK_;Адрес сегмента стека --> регистр SS
MOV SS,AX;
LEA SP,DNOST_;Адрес дна стека
; Пролог процедуры (создание кадра стека)
...
; Объектный код операторов функции main
...
; Объектный код оператора return; функции main
[ ADD SP,2*кол.лок.перем-х;Удаление локальных пер-х ]
POP BP; Восстановление регистра BP
MOV AH,4CH; Выход в MS DOS
INT 21H;
_main ENDP
Обозначим объектный код некоторой конструкции С0-программы как
объект_код (конструкция).
Ниже в обобщенном виде приведена форма объектного кода разных видов операторов языка С0, которые записаны перед своим объектным кодом в виде комментария языка ассемблера (как в выходном файле компилятора С0).
; выражение;
объект_код (выражение)
; { оператор_1; оператор_2;... оператор_n; }
объект_код (оператор_1)
объект_код (оператор_2)
...
объект_код (оператор_n)
; return выражение;
объект_код (выражение)
ADD SP,2*кол.лок.переменных
POP BP
RET 2*кол.параметров
; if (выражение) оператор
объект_код (выражение)
РОР AX; значение выражения
TEST AX,AX; проверка значения
JNZ CC_i; истина (не нуль)
JMP CC_i+1; обход оператора
СС_i:
объект_код (оператор)
СС_i+1:
; while (выражение) оператор
СС_i:
объект_код (выражение)
РОР AX;значение выражения
TEST AX,AX;проверка значения
JNZ CC_i+1;истина
JMP CC_i+2;выход из цикла
CC_i+1:
объект_код (оператор);тело цикла
JMP CС_i;переход на начало цикла
CC_i+2:
Для организации ветвлений и циклов компилятор вставляет в объектную программу метки вида СС_1, СС_2 и т. д., которые здесь обозначены как СС_i. Чтобы вставляемые транслятором метки не могли совпасть с именами функций или глобальных переменных С0-программы, транслятор добавляет к меткам символ подчеркивания “_”, который в языке ассемблера используется наравне с буквами. Этот прием называется декорированием имен. Имена функций и глобальных переменных, в свою очередь, приходится декорировать, чтобы они не совпали с именами сегментов, регистров или команд языка ассемблера.
В объектном коде операторов if и while пару соседних команд перехода нельзя заменить одной командой с противоположным условием, так как в IBM PC условный переход возможен лишь на расстояние не более 128 байтов. Если объект_код (оператор) занимает более 128 байт, возникнет ошибка. В отличие от условного перехода, безусловный переход возможен на любое расстояние.
Объектный ко д выражения состоит из групп команд, реализующих операции выражения в порядке их выполнения. Результат каждой операции (в том числе значение функции) и значение выражения помещаются в регистр AX.
Если выражение заключено в скобки, например, условие в операторах if и while или выражение-параметр в вызове функции, его значение затем помещается в стек.
Выражение из одного операнда (без операций) – переменная или константа, переводится в команду вида:
MOV AX,константа
или MOV AX,адрес-переменной
Если операндами являются константы (числа), то операция выполняется транслятором, заменяется результатом и не появляется в объектном коде, например, объектный код выражения 8 / 2 + X совпадает с объектным кодом выражения 4 + X.
Объектный код операции состоит из следующих шагов.
1. Загрузка 2-го операнда в регистр BX (для присваивания и изменения знака вместо BX используется AX).
2. Загрузка 1-го операнда в регистр AX. (кроме присваивания и изменения знака).
3. Выполнение операции над AX и BX с записью результата в AX (остаток от деления получается в DX). Функции возвращают значение в регистре AX.
4. Если операция не является последней в выражении, то ее результат помещается в стек.
Указанный порядок загрузки операндов важен, если оба операнда являются результатами других операций и поэтому выбираются из стека (2-й операнд попадает туда позже, чем 1-й операнд, и поэтому должен выбираться в первую очередь).
Операция, операнды которой являются константами, не компилируется, а интерпретируется, т. е. выполняется транслятором, например, операторы
X=Y+2*5; и X=Y+10; имеют одинаковый объектный код.
Объектный код 3-го шага в зависимости от операции имеет следующий вид.
Присваивание =:
MOV адрес-переменной,AX
Операции сравнения (==!= < > <= >=):
CMP AX,BX
MOV AX,1
усл-переход CC_i
SUB AX,AX
CC_i:
Команда условного перехода вставляется в зависимости от использованной операции сравнения.
Операция: ==!= < > <= >=
усл-переход: JE JNE JL JG JLE JGE
Арифметические операции:
+: ADD AX,BX; сложение
-: SUB AX,BX; вычитание
-: NEG AX; изменение знака
*: IMUL BX; умножение
/ или %:
CWD; преобразование делимого в 4 байта
IDIV BX; деление
Для операции %, если она последняя в выражении, добавляется команда:
MOV AX,DX
Вызов функции имя-функции (выражение_1,..., выражение_n):
объект_код (выражение_1); параметр_1 --> стек
...
объект_код (выражение_n); параметр_n --> стек
CALL имя-функции
Для ассемблирования необходимо наличие библиотеки стандартных функций - файла std.asm, который присоединяется командой INCLUDE к транслируемой программе на этапе ее ассемблирования (приложение 1). Эта команда вставляется компилятором С0 в конце сегмента кода.
Для наглядности результата трансляции компилятор C0 переносит строки исходной программы в получаемую из нее ассемблерную программу в виде строк комментария, начинающихся символом ";". За каждой такой строкой размещается объектный код, т.е. команды, полученные в результате ее трансляции (точнее - после ее ввода).
Сообщения об ошибках в исходной программе также вставляются компилятором С0 в объектный код в виде строк комментария, содержащего номер (тип) ошибки и символ "^", указывающий на текущую позицию предшествующей исходной строки в момент обнаружения ошибки. В конце объектной программы вставляется итоговое сообщение о количестве обнаруженных ошибок, дублируемое на экране.
Программа 2. Ниже приведена объектная программа для С0-программы "Коды символов" (выведена в две колонки). Два последних оператора этой программы не приведены, т. к. практически совпадают с предыдущими двумя операторами и имеют аналогичный объектный код.
Дата публикования: 2015-03-29; Прочитано: 610 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!