2812

Структура программы и модификаторы типа указателей в ОС MS-DOS

Лекция

Информатика, кибернетика и программирование

Лекция. Структура программы и модификаторы типа указателей в ОС MS-DOS В общем виде программа на языке C состоит из директив препроцессора, объявлений и определений объектов, команд, которые могут быть записаны как в одном, так и в нескольких моду...

Русский

2012-10-19

53.5 KB

4 чел.

Лекция 13

Структура программы и модификаторы типа указателей в ОС MS-DOS

В общем виде программа на языке C состоит из директив препроцессора, объявлений и определений объектов, команд, которые могут быть записаны как в одном, так и в нескольких модулях. В последнем случае при сборке программы создаётся файл проекта, в котором указываются имена всех входящих в проект файлов. Обязательно наличие одной и только одной функции main() в одном из файлов с исходными текстами. Функция main() задаёт точку входа в программу – с этой функции начинается и ей же заканчивается выполнение программы (в общем случае программа может быть завершена использованием системных функций завершения независимо от окончания функции main()).

Загрузочный модуль (типа .exe) ОС MS-DOS имеет структуру, показанную на рисунке 1.

Рис.1

Секция кода – содержит код программы (функции программиста и библиотечные функции).

Секция данных – содержит инициализируемые данные (глобальные и статические переменные) и неинициализируемые данные (константы).

Стек – используется для хранения автоматических объектов, передачи параметров и сохранения адреса возврата при вызове функции.

Ближняя куча (near heap) –динамически выделенная память.

Свободная память – память, не используемая программой.

После загрузки программы на исполнение положение и границы секций кода и данных фиксированы, начало кучи и стека (начало стека располагается снизу, а не сверху) также фиксированы, а их границы изменяются в процессе выполнения в зависимости от действий программы (направление увеличения их размеров показано стрелкой).

Регистр процессора – это ячейка памяти внутри процессора. Процессоры x86 для адресации в реальном режиме работы используют 4 сегментных регистра: CS (регистр кода, по нему происходит адресация кода программы), DS (регистр данных, по нему происходит адресация данных), SS (регистр стека, по нему производится адресация стека) и ES (дополнительный регистр, как правило дублирует регистр данных). Регистр указывает на определённый адрес в памяти, из которого можно обращаться к 64K (размер одного сегмента) ячейкам памяти по смещению относительно сегментного регистра (чтобы адресоваться к ячейкам памяти, лежащим за пределами доступных 64K, необходимо изменять значение сегментного регистра, что при программировании на языке C явно делать крайне нежелательно). Указатель называется ближним (near), если он содержит только значение смещения (сегментный адрес берётся из соответствующего сегментного регистра), данный указатель может адресоваться к 64K ячейкам памяти. Указатель называется дальним (far), если он содержит и сегментный адрес, и смещение относительно сегментного адреса, данный указатель может адресоваться к 1M ячейкам памяти. Указатель может быть указателем типа huge. Отличие указателей типа far от указателей типа huge состоит в том, что при выполнении арифметических операций с указателем типа far изменяется только смещение, сегментная часть остается постоянной, и указатель типа far может адресоваться только к 64K ячейкам памяти, чтобы его сместить, необходимо в программе явно изменять сегментную часть (проводить нормализацию), а при выполнении арифметических операций с указателями типа huge изменяться также будет и сегментная часть, поэтому можно адресоваться к любой ячейке в пределах 1M, такой указатель хранится в памяти в нормализованном виде.

Длину указателя определяет специальный модификатор (near, far или huge), используемый при объявлении указателя.

Следует учитывать, что одна ячейка памяти – это один байт. Если указатель указывает на объект, размер которого отличен от 1 байта, то в пределах одного сегмента указатель может обращаться не к 64K элементам, а к 64K/(размер типа) элементам. Например, указатель типа float в пределах сегмента будет обращаться к 64K/4=16K элементам, которые будут занимать 64K ячеек памяти.

Пример 1

float near *f;

int far *i;

char huge *c;

Модели памяти.

Особенности операционной системы MS-DOS требуют дополнительных уточнений относительно распределения памяти ЭВМ. Для этого определяются 6 моделей памяти.

Модель TINY.

Общий объём памяти для кода, данных и стека – 64K. Все указатели – ближние.

Модель SMALL.

Общий объём памяти для кода – 64K, для данных и стека – 64K. Все указатели по умолчанию – ближние, но для данных могут использоваться и дальние указатели. Начиная с этой модели в программе появляется возможность использования дальней кучи (far heap) для динамического использования памяти. К дальней куче могут обращаться только дальние указатели.

Модель MEDIUM.

Рекомендуется для больших программ с малым количеством статических данных. Общий объём памяти для кода каждого модуля – 64K, для данных и стека – 64K. Указатели данных по умолчанию – ближние, указатели функций по умолчанию – дальние.

Модель COMPACT.

Рекомендуется в случае с малым объёмом кода, но большим объёмом данных. Общий объём памяти для кода – 64K, для данных – 64K, для стека – 64K. Указатели данных по умолчанию – дальние, указатели функций по умолчанию – ближние. Начиная с этой модели отсутствует ближняя куча.

Модель LARGE.

Общий объём памяти для кода каждого модуля – 64K, для данных – 64K, для стека – 64K. Все указатели – дальние.

Модель HUGE.

Общий объём памяти для кода каждого модуля – 64K, для данных каждого модуля – 64K, для стека – 64K. Все указатели – дальние.

Данные модели памяти используются в среде Borland C++ 3.1 для ОС MS-DOS. Установка модели осуществляется в диалоговом окне Code Generation, вызываемом командой меню Options>Compiler>Code Generation.

Динамическое распределение памяти

Динамическое распределение памяти используется для выделения памяти для хранения данных в процессе работы программы, когда общий объём данных и сами данные на этапе написания программы не известны, а становятся известны лишь на этапе выполнения программы. Динамическое распределение памяти позволяет получить необходимый объём памяти для ближней или дальней кучи, в зависимости от типа указателя и модели памяти. Для этого существуют специальные библиотечные функции, описанные в файле alloc.h.

Процесс работы с динамической памятью:

  •  получение динамической памяти заданного объёма;
  •  работа с данными, распределяемыми в динамической памяти (если необходимо, то возможно перераспределение выделенного объёма памяти с сохранением находящихся в нём данных);
  •  освобождение динамической памяти по окончании работы с данными.

Для получения блока динамической памяти используются функции malloc() и calloc(). Прототипы функций:

void* malloc(size_t size);

void* calloc(size_t nitems, size_t size);

Функция malloc() в качестве аргумента принимает размер запрашиваемого блока в байтах. Функция calloc() в качестве первого аргумента принимает число элементов, под которые необходимо выделить память, в качестве второго аргумента – размер одного элемента в байтах. Тип size_t аналогичен типу unsigned int. Функции в случае успешного выделения возвращают указатель на тип void, содержащий адрес выделенного блока, который нужно явно преобразовать к указателю на необходимый тип данных. В случае ошибки (как правило связанной с тем, что такого объёма свободной памяти нет) функции возвращают значение NULL. NULL – это стандартная константа языка C, которая обозначает нулевой указатель. После выполнения динамического распределения памяти необходимо обязательно проверять, какое значение возвратили функции. Если значения указателя – NULL, то работа с памятью невозможна (в большинстве случаев следует завершить программу).

Для перераспределения уже выделенного объёма памяти используется функция realloc(). Прототип функции:

void* realloc(void* block, size_t size);

Функция изменяет размер ранее выделенного блока, сохраняя его содержимое. В качестве первого аргумента функция принимает адрес ранее выделенного блока, в качестве второго аргумента – новый размер блока, при этом новый блок может оказаться в другом месте кучи. Функция в случае успешного выделения возвращает указатель на тип void, содержащий адрес нового блока, который нужно явно преобразовать к указателю на необходимый тип данных. Функция возвращает NULL, если размер нового блока больше размера старого блока, и в памяти нет свободного места для размещения нового блока.

Для освобождения блока динамической памяти используется функция free(). Прототип функции:

void free(void* block);

Функция выполняет освобождение блока памяти, адрес которого принимает в качестве аргумента. Все блоки динамической памяти должны быть освобождены по окончании работы с ними, иначе они так и останутся занятыми по окончании работы программы до перезагрузки системы, что приведёт к утечке оперативной памяти.

В среде Borland C++ 3.1 для работы с дальней кучей необходимо использовать дальние указатели и соответствующие функции, но с приставкой far.

Пример 2

#include <stdio.h>

#include <alloc.h>

#include <stdlib.h>

void main(void)

{

int n,m;

printf("Input string number\n");

scanf("%d",&n);

printf("Input column number\n");

scanf("%d",&m);

float *f,sum=0;

if((f=(float*)malloc(n*m*sizeof(float)))==NULL)

{

 printf("System do not have free memory\n");

 exit(1);

}

printf("Input matrix");

for(int i=0;i<n;i++)

 for(int j=0;j<m;j++)

 {

  printf("\nmatrix[%d][%d]=",i,j);

  scanf("%f",(f+i*m+j));

 }

if((f=(float*)realloc(f,(n+1)*m*sizeof(float)))==NULL)

{

 printf("System do not have free memory\n");

 exit(1);

}

for(int t=0;t<m;t++,sum=0)

{

 for(int j=0;j<n;j++)

  sum+=*(f+j*m+t);

 *(f+n*m+t)=sum;

}

for(int k=0;k<n+1;k++)

{

 printf("\n");

 for(int j=0;j<m;j++)

  printf("%f\t",*(f+k*m+j));

}

free(f);

}


 

А также другие работы, которые могут Вас заинтересовать

25738. Законодательство в сфере журналистики. Закон о СМИ 25.88 KB
  Право на получение информации одновременно означает обязанность государственных органов и органов местного самоуправления всех властных и общественных структур дать ответ на обращение к ним гражданина. Право производить и распространять информацию представляет собой творческий процесс по созданию информации в любой форме от книги до сигналов в космические дали и свободному ее распространению в том числе с помощью различных технических средств. Недопустимость идеологической ангажированности средств массовой информации закреплена в статье...
25739. Журналистское произведение как текст – жанровые разновидности 29.76 KB
  В прессе предлагают разделять тексты на 5 групп: оперативноновостные заметка оперативноисследовательские интервью репортажи отчеты исследовательсконовостные комментарий рецензия корреспонденция исследовательские статья письмо обозрение исследовательскообразные очерк фельетон. Информационные новость заметка интервью репортаж отчет реплика Аналитические корреспонденция статья комментарии рецензия обозрение Художественнопублицистические очерк зарисовка эссе сатирические жанры памфлет...
25740. Явления демассификации и дигитализации СМИ 19.61 KB
  Явления демассификации и дигитализации СМИ Под воздействием новых информационных технологий происходят значительные изменения в области массовых коммуникаций. Рассмотрим основные процессы лежащие в основе модификации современной системы СМИ. Под этим подразумевается перевод содержания СМИ во всех его формах текстовой графической звуковой в цифровой формат понятный современным компьютерам. Дигитализация устраняя различия между отдельными СМИ и уравнивая их содержание прокладывает дорогу их конвергенции.
25741. Социально-политические предпосылки возникновения журналистики 21.3 KB
  Социальнополитические предпосылки возникновения журналистики Этапы возникновения журналистики: Изобретение письменности возможность передачи информации из поколения в поколение; Изобретение книгопечатания 1450г. Появилась потребность в директивной управленческой информации более массового свойства нежели информация межличностного или коллективного публичного общения а также в формировании общественного мнения. Носителем информации служили дощечки покрытые гипсом. К материальнотехническим предпосылкам возникновения журналистики...
25742. Особенности информационной инфраструктуры в национальных границах различных стран 25.07 KB
  С точки зрения теории и практики массовой информации можно рассматривать четыре виды инфраструктуры: компьютерную информационную интернетинфраструктуру социальную. Интернетинфраструктура объем электронной торговли; количество домашних пользователей Интернета; количество пользователей интернета в бизнесструктурах; количество пользователей интернета использующих его для интернета. для определения рейтинга стран мира является особое внимание к деятельности связанной с Интернетом. В то время как американские фермеры не первый год...
25743. Российская информационная инфраструктура 19.57 KB
  Компьютерная количество ПК на душу населения; количество ПК на семью; количество ПК установленных в государственном секторе и в коммерческих структурах; количество ПК для учебных заведений; ПК объединенных в сети; расходы на компьютерное оборудование и программное обеспечение ПО. Информационная количество телефонных линий на семью; количество сбоев на линии; стоимость переговоров на местных линиях; количество сотовых телефонов на душу населения; количество телевизоров на душу населения; число абонентов кабельного ТВ....
25744. Профессионально-этические правила и нормы в деятельности журналиста 31.71 KB
  Профессиональноэтические правила и нормы в деятельности журналиста Со времени появления независимой журналистики у нас в стране этические вопросы её существования становятся всё острее. В нашем обществе успел уже сформироваться негативный образ жёлтой прессы продажных журналистов и просто журналюг. С одной стороны журналистика считается престижной профессией. С другой стороны сохраняется откровенно настороженное отношение к журналистам со стороны не только персон которые могут объектами журналистского профессионального интереса но...