В Турбо Паскале принята такая структура распределения памяти: выделяется сегмент для кода (т е для команд откомпилированной программы.), обозначаемый CS. Адреса команд модуля имеют общий сегментный адрес и отличаются смещением (Offset). Поэтому размер откомпилированного модуля (в том числе - главной программы) не может превышать 64Кб. Аналогично, выделяется сегмент для данных (DS) и сегмент для стека (SP) (в стеке временно хранятся данные и код подпрограммы - на время ее исполнения)
Вы можете узнать сегментную часть адреса и смещение для элемента программы.
Программа, демонстрирующая работу с адресами:
type arab = array [1..10] of extended;
var xx,xx2: double; po1: ^double; w1: longint;
zz : ^arab;
function kub(yy: double): double;
begin kub := sqr(yy)*yy;
writeln('yy : SEG= ',seg(yy),' OFS= ', Ofs(yy));
end;
begin
write('Введи число -> '); readln(xx);
xx2:= kub(xx);
writeln('Число ',xx:0:1,' в кубе = ',xx2:0:1);
writeln('----- Адреса: -----');
writeln('xx : SEG= ',seg(xx),' OFS= ', Ofs(xx),' 1-й способ');
writeln('xx2: SEG= ',seg(xx2),' OFS= ', Ofs(xx2));
writeln('po1: SEG= ',seg(po1),' OFS= ', Ofs(po1));
writeln('w1 : SEG= ',seg(w1),' OFS= ', Ofs(w1));
writeln('zz : SEG= ',seg(zz),' OFS= ', Ofs(zz));
writeln('kub: SEG= ',seg(kub),' OFS= ', Ofs(kub));
po1 := @xx;
w1:= longint(po1) shr 16;
write('SEG_xx = ',w1,' ');
w1:= longint(po1) shl 16 shr 16;
writeln('OFS_xx = ',w1,' - 2-й способ');
new(po1); po1^ := kub(xx);
writeln('po1^: SEG= ',seg(po1^),' OFS= ', Ofs(po1^));
dispose(po1);
new(zz); zz^[1]:= 2; zz^[2]:= 4.6;
writeln('zz^[1]: SEG= ',seg(zz^[1]),' OFS= ', Ofs(zz^[1]));
writeln('zz^[2]: SEG= ',seg(zz^[2]),' OFS= ', Ofs(zz^[2]));
writeln('zz^[3]: SEG= ',seg(zz^[3]),' OFS= ', Ofs(zz^[3]));
readln;
end.
---- Результаты работы: -----
Введи число -> 3
yy : SEG= 21692 OFS= 16372
Число 3.0 в кубе = 27.0
----- Адреса: -----
xx : SEG= 21647 OFS= 82 1-й способ
xx2: SEG= 21647 OFS= 90
po1: SEG= 21647 OFS= 98
w1 : SEG= 21647 OFS= 102
zz : SEG= 21647 OFS= 106
kub: SEG= 21160 OFS= 18
SEG_xx = 21647 OFS_xx = 82 - 2-й способ
yy : SEG= 21692 OFS= 16372
po1^: SEG= 22716 OFS= 0
zz^[1]: SEG= 22716 OFS= 0
zz^[2]: SEG= 22716 OFS= 10
zz^[3]: SEG= 22716 OFS= 20
Объявление: Procedure New(Var P : Pointer [, Init : Constructor ]); Замечания:Объявление New было расширено, так что теперь она может также инициализировать объект распределенный в куче, если вы передаете конструктор этого объекта как второй параметр, например:
Объявление: Procedure Dispose(Var P : Pointer [ , Destructor ]);Объявление процедуры Dispose, было расширено так, что теперь она может также освобождать память занятую объектом, распределенным в куче, если вы передаете деструктор этого объекта как второй параметр, например:
Объявление: Procedure GetMem(Var P : Pointer; Size : Word); Замечания:Параметр P - переменная любого указательного типа. Параметр Size - выражение, определяющее размер динамической переменной в байтах. Недавно созданная переменная может быть вызвана как P^.
Объявление: Procedure FreeMem(Var P : Pointer; Size : Word); Замечания:Параметр P - переменная любого указательного типа, предварительно распределенная в памяти процедурой GetMem или та, которой было присвоено значение оператором присваивания.
Объявление: Function Seg(X) : Word; Замечания:Параметр X - любая переменная или идентификатор процедуры или функции. Результат типа Word, является сегментной частью адреса X.
Объявление: Function Ofs(X) : Word; Замечания:Параметр X - это любая переменная или идентификатор процедуры или функции. Результат типа Word - смещение адреса X в памяти.
Объявление: Procedure Move(Var Source, Dest; Count : Word); Замечания:Копирует определенное число байт (Count) из Source в Dest. Никакая проверка диапазона не выполняется. Всегда, когда возможно, используйте SizeOf, чтобы определять количество копируемых байтов.
Объявление: Procedure FillChar(Var X; Count : Word; Value); Замечания: X - буфер, который нужно заполнить Count - количество символов Value - заполнитель (типа Byte или Char) Не выполняет проверки диапазона.
Объявление: Function Addr(X) : Pointer; Замечания:Параметр X - идентификатор переменной, процедуры или функции. Результат - указатель на X. Как и NIL, результат функции Addr совместим со всеми типами указателей.
Объявление: Function CSeg : Word; Замечания:Результат типа Word - сегментная часть адреса сегмента кода, в котором была вызвана функция CSeg.
Объявление: Function DSeg : Word; Замечания:Результат типа Word - сегментная часть адреса сегмента данных.
Объявление: Function SSeg : Word; Замечания:Результат типа Word является сегментной частью адреса сегмента стека.
Объявление: Function SPtr : Word; Замечания:Возвращает смещение указателя на вершину стека внутри сегмента стека.
Объявление: Function MemAvail : Longint; Замечания:MemAvail возвращает сумму размеров всех свободных блоков в куче. Обратите внимание, что непрерывный блок памяти возвращенного размера, вряд ли будет доступен из-за фрагментации кучи. Чтобы найти самый большой свободный блок, вызовите MaxAvail.
Объявление:
Function MaxAvail : Longint;
Замечания:
Возвращает больший из:
- Самых больших свободных блоков внутри области менеджера
управления динамической памятью
- Глобальной кучи Windows
Значение соответствует размеру самой большой динамической переменной,
которая может быть распределена.
Объявление:
Function Ptr(Seg, Ofs : Word) : Pointer;
Замечания:
Seg и Ofs - выражения типа Word.
Результат - указатель, показывающий на
адрес Seg:Ofs. Результат, возвращаемый Ptr,
совместим со всеми типами
указателей (как и NIL).
Например:
If Byte(Ptr($40, $49)^) = 7 Then WriteLn('Видеорежим - монохром');