Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Объектный код компилятора C0



Объектный код, т. е. результат трансляции С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 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.015 с)...