Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы си++.pdf
Скачиваний:
55
Добавлен:
09.04.2015
Размер:
455.01 Кб
Скачать

(4)программа-ассемблер переводит ассемблерный код на машинный язык, создает

объект ный модуль программы с расширением .obj и сохраняет его на диске. Файл, содержащий скомпилированную программу, – это объектный модуль программы.

(5) – программа-компоновщик (редактор связей, Linker) объединяет объектный код программы (совместно компилируемые модули) с объектными кодами используемых ею библиотечных

функций (библиотечные файлы имеют расширение .lib) и стандартным кодом начальной загрузки, в результате чего создается исполняемый загрузочный модуль программы – файл с расширением

.exe, сохраняемый на диске. Обычно программы содержат ссылки на функции, определенные вне самой программы: в стандартных или личных библиотеках, а объектный код содержит «дыры» изза этих отсутствующих частей; компоновщик заполняет эти «дыры».

(6) – программа-загрузчик размещает скомпонованную программу в памяти (забирает исполняемый код с диска и размещает его в памяти).

Язык Си++ имеет прямой выход на компьютерную архитектуру, многие его компоненты напрямую на нее отображаются. Базовые типы данных совпадают с основными формами представления данных в процессоре, имеется прямое соответствие между переменными и машинными словами, набор операций соответствует общепринятому минимуму для системы команд, указатели интерпретируются как адреса, имеется возможность работы с памятью на низком (архитектурном) уровне. Поэтому Си++ можно назвать машинно-независимым Ассемблером. Особенности выполнения указанных действий зависят от конкретного компилятора языка С++ и операционной системы, в которой он работает. Технические подробности следует изучить по документации конкретного программного продукта.

Технологический цикл обработки программы

Технологический цикл обработки программы выглядит следующим образом:

перевод с языка высокого уровня на машинный язык

создание исполняемого Создание (загрузочного) модуля

исходного

текста

Компи- Компоновка ляция

 

 

 

 

 

 

 

 

 

 

Отладка,

 

 

 

 

 

 

 

 

 

 

тестиро-

 

Исправление

 

 

 

 

 

 

 

вание,

 

 

 

 

 

 

 

 

 

синтаксических

 

 

 

 

 

 

 

выпол-

 

ошибок

Исправление

 

 

нение

 

 

 

 

 

 

семантических

 

 

 

 

 

 

 

 

ошибок

 

 

 

 

 

 

 

 

 

Синт аксис языка программирования описывает сист ему правил написания различных языковых конст рукций; нарушение этих правил приводит к синт аксическим ошибкам,

выявляемым на этапе компиляции программы в процессе синт аксического анализа;

Семант ика языка программирования – правила инт ерпрет ации операт оров – определяет

смысл языковых конст рукций, последовательность действий, которые выполнит компьютер при реализации написанного; нарушение этих правил приводит к семант ическим ошибкам, выявляемым в процессе семант ического анализа (трудно, а практически вообще не выявляемым на этапе компиляции и трудно выявляемым на этапе отладки и даже эксплуатации программы).

Особенности внутреннего представления программы и ее исполнения

Для понимания и осознанного использования многих особенностей языка программирования полезны знания о внутреннем представлении программы и принципах ее исполнения, а также о

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

12

 

компьютерной архитектуре. Попробуем представить все это на самой примитивной модели.

Организация памяти компьютера

Все данные, хранящиеся в памяти компьютера, представляются в двоичной системе счисления в виде машинных слов – наборов двоичных разрядов (совокупность битов – нулей и единиц). Биты объединяются в последовательности: байты, слова и т.д. Минимальный размер машинного слова для хранения, обработки и передачи данных – 8 битов (1 байт). Все остальные слова кратны ему. Ст андарт ное машинное слово имеет разрядность, соответствующую разрядности процессора (32 разряда или 4 байта).

Какой смысл заключен в данных, какими символами они выражены – буквенными или цифровыми, что означает то или иное число – все это определяется программой обработки. Все данные, необходимые для решения практических задач, подразделяются на несколько типов, причем понятие тип связывается не только с представлением данных в адресном пространстве, но и со способом их обработки. Данные могут быть отнесены к одному из двух типов: основному (простому), форма представления которого определяется архитектурой компьютера, или сложному, конструируемому пользователем для решения конкретных задач. Данные простого типа это – символы, числа и т.п. элементы, дальнейшее дробление которых не имеет смысла. Из элементарных данных формируются структуры (сложные типы) данных.

Основу компьютерной архитектуры составляет прямо адресуемая памят ь: массив элементарных ячеек памяти, номера кот орых называют ся адресами. Каждому участку оперативной памяти, который может вместить один байт или слово, присваивается адрес (порядковый номер). Как адрес памяти, так и ее содержимое представляют собой машинные слова.

Для представления содержимого машинных слов используется шестнадцатеричная система счисления. В дальнейшем описании мы будем применять более привычные десятичные значения, не забывая, что в реальности имеем дело с двоичными (шестнадцатеричными) эквивалентами.

Поэтому на самом низком уровне адрес можно рассматривать как целое число. Все формы представления данных (целые со знаком и без него, вещественные, символы) проецируются в двоичное представление и в машинные слова. Но!!!: хранятся числовые значения в памяти, начиная с младшего байта, в порядке, обратном привычному нам при записи чисел (Рис.1.4).

Процессор имеет в своем составе набор машинных слов – регист ров. В зависимости от назначения они могут хранить как данные, так и адреса памяти.

Рис. 1.4. Организация памяти компьютера

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

13

 

Сегментация программы

Следующий важный принцип организации памяти – сегментация. Сегмент ом называется непрерывная область памяти, хранящая данные одного вида (назначения) и имеющая собственную систему относительной адресации и ограничения доступа. К программированию это имеет отношение потому, что при трансляции разные компоненты программы попадают в различные сегменты программного кода.

Одновременное нахождение в памяти «алгоритма» и данных соответствует принципу хранимой программы, который заключается в том, что программный код хранится в той же самой памяти, что и обрабатываемые данные, и в свою очередь сам представляет собой специфические данные, с которыми работает процессор во время выполнения программы. В настоящее время применяется немодифицируемый программный код. Это, в свою очередь, означает, что несколько программ могут его читать и исполнять, не мешая друг другу, в то м числе и на физически параллельных процессорах.

Компоненты программы находятся в памят и, которая, в принципе, является общей для них, но логически разделяется на области, именуемые сегмент ами: прежде всего, это сегмент данных, содержащий данные программы, и сегмент кода, в котором находится алгоритмическая компонента (выражения, операторы).

Сегментация поддерживается в процессоре при помощи регистров двух видов. Базовый регист р сегмент а содержит его начальный адрес. Регистры, работающие с данными сегмента, содержат относительный адрес данных от начала сегмента, или смещение. Результирующий адрес получается путем сложения содержимого этих регистров. Таким образом, каждый сегмент имеет собственную «систему координат», связанную с его началом (Рис.1.5). Если программа использует только сегментную адресацию, то сегменты можно перемещать по памяти при сохранении работоспособности программы: достаточно перенастроить соответствующие им базовые регистры.

Выполняемая программа состоит из нескольких сегментов. Некоторые из них создаются при трансляции, другие – при загрузке и при работе программы. В принципе, программа может иметь несколько сегментов одного вида.

Рис. 1.5. Сегментация программы

Сегмент

Регистры

Что содержит

Когда создается

Сегмент команд

CSсегментный,

Программный код (операции,

трансляция

 

IPадрес команды

операторы)

 

Сегмент данных

DS – сегментный

Глобальные (статические)

трансляция

 

 

данные

 

Сегмент стека

SS – сегментный,

Локальные данные функций,

при загрузке

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

14

 

 

SP– указатель стека

«история» работы

 

 

 

программы

 

Динамическая

DS – сегментный

Динамические переменные,

при загрузке,

память

 

создаваемые при работе

выполнении

 

 

программы

 

Динамически

CS– сегментный,

Программный код

при загрузке

связываемые

IP– адрес команды

разделяемых библиотек

 

библиотеки

 

 

 

(DLL)

 

 

 

Следующий элемент архитектуры тоже имеет отношение к внутреннему представлению программы – вирт уальное адресное прост ранст во (вирт уальная памят ь). Его идея состоит в том,

что каждая программа имеет свое, независимое от других, виртуальное адресное пространство (виртуальную память), в котором размещаются сегменты программы, определяются адреса и т.п. В процессоре имеется скрытая от программ система отображения виртуальных адресов на физические адреса., Вирт уальное адресное прост ранст во находится под управлением операционной системы и реализует защиту памяти программ, ее разделение (сегменты динамически связываемых библиотек), загрузку программы в память «по частям» и иллюзию наличия неограниченной памяти. Для нас из всего этого важно то, что внутренне представление программы в виртуальной памяти занимает все адресное пространство, как будто других программ и операционной системы в памяти нет вовсе.

Процесс исполнения программного кода

Процесс исполнения программного кода в общих чертах представлен на Рис.1.6. Действующими лицами этого процесса являются:

программный код – последовательность команд, размещенная в сегменте кода (CS), на начало которого ссылается одноименный регистр процессора;

Рис. 1.6. Кодовое представление программы

каждая команда имеет в сегменте свой относительный адрес (от начала сегмента), регистр процессора IP (Instruction Pointer) содержит адрес очередной выполняемой команды. В программировании на языках высокого уровня с IP ассоциируется очень важное понятие – т екущая т очка выполнения программы;

команда представляет собой машинное слово, обычно переменной длины, и

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

15

 

состоит из нескольких полей. Обязательным полем является код операции, который указывает на выполняемое командой действие. Совокупность команд процессора называется сист емой команд. В системе команд обязательно присутствуют следующие виды операций:

o команды перемещения и обработ ки данныхвыполняют перенос данных между ячейками памяти и регистрами данных процессора, а также все действия по их обработке (mov, add, sub);

o команды проверки сост ояний (условий) проверяют результат выполнения операций, состояния регистров процессора, устройств ввода-вывода и т.п. (test); o команды условного и безусловного переходов определяют адрес следующей команды (выполняют переход в программе) в зависимости от результата проверки некоторого условия. Если условие выполняется, то происходит переход, иначе выполняется следующая за ней команда.

вторым элементом команды являются операнды: в команде в явном или неявном виде должны содержаться адреса операндов; это могут быть регистры процессора, содержащие данные, и ячейки памяти;

переменные, используемые в программы, при трансляции «становятся» областями памяти в различных сегментах данных (сегменты данных, стека, динамической памяти), где получают свои адреса. В командах, работающих с памятью, в том или ином виде имеется информация, позволяющая вычислить (или просто взять) этот адрес;

в нашем примере большинство команд переноса и обработки данных являются двухадресными – результат операции совпадает с первым операндом (команду сложения add ax, 454 следует понимать как ax=ax+b);

в нашем примере используется непосредст венная адресация для констант (их значение находится в самой программе, add ax, #10) и прямая адресация для ячеек памяти (в команде содержится их адрес, add ax, 454);

в командах безусловного (jmp) и условного (jmi – «переход, если меньше нуля») должен быть определен адрес следующей команды: в нашем примере он задан в относительной форме – в виде смещения (расстояния) от следующей команды до той, куда производится переход.

Выполнение программы происходит, в общих чертах, таким образом:

процессор, используя регистры CS:IP выбирает из памяти очередную команду и расшифровывает ее. После этого IP увеличивается и ссылается на следующую команду (в зависимости от длины текущей, например, IP=IP+3);

если это команда переноса или перемещения данных, то процессор формирует адреса операндов в зависимости от способа адресации, после чего выполняет действия, указанные в команде;

если это команда проверки условия, то проверяется указанный операнд, и устанавливаются признаки выполнения различных условий (равно 0, не равно 0, больше 0 и т.п.);

если в команде условного перехода проверяемое условие выполняется, то программа «переходит» по адресу, содержащемуся в команде. В нашем примере это смещение из команды просто добавляется к IP (IP=IP+<смещение>). Иначе ничего не происходит и выбирается следующая команда.

Сравнивая систему команд компьютера с другими способами представления программ в известных технологиях программирования, можно заметить, что внутреннее представление

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

16