Лабораторная работа №23 / Лаба 2 по ОС
.docМИНИСТЕРСТВО НАУКИ И ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ
САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ
ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
КАФЕДРА МОЭВМ
ОТЧЕТ
ПО ЛАБОРАТОРНОЙ РАБОТЕ №2
«Создание make-файла»
по дисциплине
«Операционные системы»
Вариант 2
ПРЕПОДАВАТЕЛЬ: АЛЕКСЕЕВ А.Н.
ВЫПОЛНИЛА СТ. ГР. 3351 ФКТИ: БАХВАЛОВА Ю.С.
САНКТ-ПЕТЕРБУРГ
2005
1. Постановка задачи
- Написать программу, решающую задачу в соответствии с выданным вариантом. Входные параметры задаются с клавиатуры. Формат ввода и ограничения определяется самостоятельно.
- Написать файл с набором правил сборки и линковки программы (Makefile) с целями all и clean. По all программа должна собираться, а по clean удалять все созданные бинарные файлы.
- Получить из исполняемого файла список символов для линковщика с помощью утилиты nm. Найти символы, соответствующие функциям из разработанной программы.
- Для любой функции программы получить с помощью утилиты objdump ее бинарный и ассемблерный код с соответствующими сороками на С.
- С помощью утилиты objdump, определить в какой секции хранятся символьные строки, и в какой исполняемый код программы.
- Вывести ELF заголовок программы с помощью утилиты readelf
Найти медиану введенной последовательности. Входные параметры: длинна последовательности и значения ее элементов.
2. Формат ввода и ограничения
С клавиатуры вводится количество элементов последовательности (от 1 до 100). Далее вводятся значения каждого из элементов, значения – вещественные. Программа находит медиану методом Хоара.
Медиана последовательности – это:
a-последовательность из n элементов
1 k n
a[1..k)<a[k]<a[k+1, n]
Диаграмма: n=2q+1
n-k
k-1
3. Текст программы
// lab2os.cpp
#include<iostream>
#include<math.h>
#include<stdlib.h>
#include"os2.h"
int main()
{
double ar[100];
int n;
std::cout<<" ***Laboratory work 2: Search mediana***"<<"\n"<<"\n";
std::cout<<"Enter count of elements: ";
std::cin>>n;
if (div(n,2).rem!=0)
{
for (int i=1;i<=n;i++)
{
std::cout<<"Enter element "<<i<<": ";
std::cin>>ar[i];
};
mediana(1,n,(div(n,2)).quot+1,ar);
printAr(n,ar);
}
else std::cout<<"This elements have no mediana!"<<"\n";
return 0;
}
// os2.cpp
#include"os2.h"
#include<iostream>
#include<math.h>
int Partition(int i,int j,double ar[])
{
int l,r,num;
double q,s;
l=i; r=j;
num=l+(div(r-l,2)).quot;
q=ar[num];
while (l<r)
{
s=ar[l];
ar[l]=ar[r];
ar[r]=s;
while ((ar[l]<=q)&(l!=num))
{
l++;
};
while ((ar[r]>=q)&(r!=num))
{
r--;
};
};
return r;
}
void printAr(int n,double ar[])
{
std::cout<<"Massiv is:"<<"\n";
for (int i=1; i<=n; i++)
{
std::cout<<ar[i]<<" ";
};
std::cout<<"\n";
}
void mediana(int i,int j,int k,double ar[])
{
int p;
p=Partition(i,j,ar);
if (p<k)
{
mediana(p+1,j,k,ar);
}
else
if (p>k)
{
mediana(i,p-1,k,ar);
}
else
if (p==k)
{
std::cout<<" ---Mediana is ar["<<p<<"]="<<ar[p]<<"\n";
}
}
// os2.h
// Function of share massiv in two parts
int Partition(int i,int j,double ar[]);
// Priint massiv
void printAr(int n,double ar[]);
// Search mediana
void mediana(int i,int j,int k,double ar[]);
4. Make-файл
Создали makefile: mp.makefile с целями all и clean. Он автоматически собирает программу:
make –f mp.makefile all. И удаляет промежуточные файлы: make –f mp.makefile clean.
Текст файла mp.makefile:
all: myprog
myprog: lab2os.o os2.o
g++ lab2os.o os2.o -o myprog
lab2os.o: lab2os.cpp os2.h
g++ -g -Wall -c lab2os.cpp
os2.o: os2.cpp os2.h
g++ -g -Wall -c os2.cpp
clean: lab2os.o os2.o
rm lab2os.o
rm os2.o
rm myprog
Ключи g++:
-c |
Отменить фазу редактирования связей и создавать объектный файл даже в случае программы, состоящей только из одного модуля. |
-g |
Сгенерировать дополнительную информацию для отладчика sdb(1). |
-О |
Включить оптимизацию объектного кода. |
-L каталог |
Дополнить каталогом список каталогов, которые содержат объектные библиотечные модули |
-l библиотека |
Скомпоновать с объектной библиотекой |
-I каталог |
Изменить алгоритм поиска включаемых (посредством директивы #include) файлов, имена которых не начинаются с символа /, а именно: сначала искать в указанном каталоге, а затем уже в каталогах стандартного списка. Так, включаемые файлы, чьи имена заданы в двойных кавычках, сначала ищутся в каталоге, содержащем файл, затем в каталогах, указанных с помощью опции -I, а затем уже в каталогах стандартного списка. Включаемые файлы, чьи имена заданы в угловых скобках, не ищутся в каталоге, содержащем файл. |
5. Отладчик GDB
GDB предоставляет все перечисленные возможности. Он называется отладчиком на уровне исходного текста, создавая иллюзию, что Вы выполняете операторы C++ из Вашей программы, а не машинный код, в который они действительно транслируются.
Для иллюстрации мы используем систему, которая компилирует программы на C++ в исполняемые файлы, содержащие машинный код. В результате этого процесса информация об оригинальном коде C++ теряется при трансляции. Отдельный оператор C++ обычно преобразуется в несколько машинных команд, а большинство имен локальных переменных просто теряется. Информация о именах переменных и операторах C++ в Вашей исходной программе не является необходимой для ее выполнения. Поэтому, для правильной работы отладчика на уровне исходного текста, компилятор должен поместить в программу некоторую дополнительную информацию. Обычно ее добавляют к информации, используемой компоновщиком, в исполняемый файл.
Чтобы указать компилятору (gcc), что Вы планируете отлаживать Вашу программу, и поэтому нуждаетесь в дополнительной информации, добавьте ключ -g в опции компиляции и компоновки. Например, если Ваша программа состоит из двух файлов main.C и utils.C, Вы можете откомпилировать ее командами
gcc -c -g -Wall main.C
gcc -c -g -Wall utils.C
gcc -g -o myprog main.ob utils.o
6. Команда nm
Команда nm выдает на стандартный вывод таблицу имен для каждого об ектного файла, указанного в командной строке. Файл может быть как перемещаемым, так и абсолютным об ектным файлом, или может быть архивом из таких файлов. Для каждого элемента таблицы выдается следующая информация:
Name |
Имя элемента таблицы. |
Value |
Значение, выражаемое как смещение или адрес, в зависимости от класса хранения. |
Class |
Класс хранения. |
Type |
Информация о типе. Если элемент описывает экземпляр структуры или об единения, то за типом будет выведено имя структуры или об единения (например, struct-имя). Если элемент соответствует массиву, то размер массива будет указан за типом (например, char[n][m]). Заметим, что для наличия этой информации файл должен быть откомпилирован командой cc(1) с опцией -g. |
Size |
Размер в байтах, если он определен. Заметим, что для наличия этой информации файл должен быть откомпилирован командой cc(1) с опцией -g. |
Line |
Номер строки в файле с исходным текстом, в которой об ект определяется, если эта информация имеет смысл. Заметим, что для наличия этой информации файл должен быть откомпилирован командой cc(1) с опцией -g. |
Section |
Для об ектов с классом хранения статический (static) и внешний (extern) указывается секция, которой принадлежит об ект: секция команд (.text), секция инициализированных данных (.data) или секция неинициализированных данных (.bss). |
Для нашего случая используем nm myprog
7. Утилита objdump
1) Для любой функции программы получить с помощью утилиты objdump ее бинарный и ассемблерный код с соответствующими сороками на С
objdump –d os2.o
2) С помощью утилиты objdump, определить в какой секции хранятся символьные строки, и в какой исполняемый код программы
objdump –h myprog
8. Утилита readelf
Вывести ELF заголовок программы с помощью утилиты readelf
readelf –h lab2os.o
9. Выводы
В ходе выполнения данной лабораторной работы мы научились автоматически собирать программу, написанную на С++, при помощи make-файла. Использовать отладчик gdb, а также использовать такие утилиты, как nm, objdump, readelf.