Лабораторная работа: Модульное программирование
смещение: 0000 0101 0011 0010 = 00532
---------------------- - -------------------------------
Адрес: 0010 1111 1101 0111 0010 = 2FD72
Участок памяти величиной 16 байт называется параграфом, поэтому говорят, что сегмент всегда начинается на границе параграфа.
Начальный адрес сегмента всегда является 20-битовым числом, но сегментный регистр имеет всего 16 битов - поэтому младшие 4 бита всегда предполагаются равными нулю. Это означает - как было уже сказано - что начало сегмента может находиться только в адресах памяти, кратных 16, т.е. адресах, в которых последние 4 бита (или один шестнадцатиричный разряд) равен нулю. Поэтому если регистр DS содержит значение 2F84, то фактически сегмент данных начинается в адресе 2F840.
Стандартная запись адреса имеет форму сегмент: смещение ; например, предыдущий адрес можно записать как 2F84: 0532. Отметим, что поскольку смещения могут перекрываться, данная пара сегмент: смещение не является уникальной; следующие адреса относятся к одной и той же точке памяти:
0000: 0123
0002: 0103
0008: 00A3
0010: 0023
0012: 0003
Сегменты могут (но не должны) перекрываться. Например, все четыре сегмента могут начинаться с одного и того же адреса, что означает, что вся ваша программа в целом займет не более 64 Кб - но тогда в пределах этой памяти должны поместиться и коды программы, и данные, и стек.
2.1 Виды моделей памяти
В 16-разрядных программах вы можете использовать 6 моделей памяти: крохотную, малую, среднюю, компактную, большую и огромную.
Tiny (крохотная). Эта модель памяти используется в тех случаях, когда абсолютным критерием достоинства программы является размер ее загрузочного кода. Это минимальная из моделей памяти. Все четыре сегментных регистра (CS, DS, SS и ES) устанавливаются на один и тот же адрес, что дает общий размер кода, данных и стека, равный 64К. Используются исключительно ближние указатели.
Small (малая). Эта модель хорошо подходит для небольших прикладных программ. Сегменты кода и данных расположены отдельно друг от друга и не перекрываются, что позволяет иметь 64К кода программы и 64К данных и стека. Используются только указатели near.
Medium (средняя). Эта модель годится для больших программ, для которых не требуется держать в памяти большой объем данных. Для кода, но не для данных используются указатели far. В результате данные плюс стек ограничены размером 64К, а код может занимать до 1М.
Compact (компактная). Лучше всего использовать эту модель в тех случаях, когда размер кода невелик, но требуется адресация большого объема данных. Указатели far используются для данных, но не для кода. Следовательно, код здесь ограничен 64К, а предельный размер данных - 1 Мб.
Large (большая). Модели large и huge применяются только в очень больших программах. Дальние указатели используются как для кода, так и для данных, что дает предельный размер 1 Мб для обоих.
Huge (огромная). Дальние указатели используются как для кода, так и для данных. Borland C обычно ограничивает размер статических данных 64К; модель памяти huge отменяет это ограничение, позволяя статическим данным занимать более 64К.
Для выбора любой из этих моделей памяти вы должны либо воспользоваться соответствующим параметром меню интегрированной среды, либо ввести параметр при запуске компилятора, работающего в режиме командной строки.
2.2 Размещение исполняемого файла в ОЗУ в модели large
Модели памяти устроены по-разному. Рассмотрим расположение областей памяти в модели large.
Область кода содержит машинные коды функций программы. Функции, присоединенные к exe-файлу на стадии линковки, размещаются вне области кода.
Область данных содержит глобальные и статические переменные, строковые константы.
В стеке размещаются локальные переменные, параметры, передаваемые функциям, и ряд других данных. Как правило, стек растет сверху вниз, занимая пульсирующую непрерывную область. В случае переполнения стека происходит его "налезание" стека на область данных и выдается соответствующее сообщение. Проверка стека увеличивает время работы программы и ее можно отключить в Options-Entry/Exit Code Generation-Stack options-Test stack overflow.
В кучу данные помещаются только по указанию программиста и не имеют имени. К ним можно обратиться только по адресу, расположенному в локальной или глобальной переменной.
Рис.1. Сегментация для модели памяти Large
3. Передача данных в функцию
Си - язык сугубо процедурный и основной логической единицей программы является функция. Формат описания функции следующий:
[тип возвращаемого значения] имя_функции (список параметров)