TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

Документация   

Странности

FAQ

Ссылки

Форум

Гостевая книга

Рассылка

Благодарности

Об авторе

59 Please explain Turbo Pascal memory addressing to me.

 A: This is far from an 
easy question, but let's see what we can do.
The origins of the difficulties are in the design of the 8086 chip
which still restricts all Turbo Pascal applications (which contrary
to Borland Pascal use the original real mode). The 8086 (aka real
mode) addressing is based on 16-bit registers. As you probably 
know
2^16 is 65536 which means that you cannot directly point to all
addresses of the lower and upper memory, which ranges from 0 to
1048575 (2^20-1). Thus all the memory addresses are pointed to 
into
two parts in TP programs, the segment and the offset. The 
following
example of the PC's memory illustrates.
  Decimal  Hexa-
  address  decimal  Segment  Offset  What
        0   $00000    $0000   $0000  Conventional memory starts
     1043   $00413    $0040   $0013  Base memory in Kb, a word
   655359   $9FFFF    $9000   $FFFF  Conventional memory ends
   655360   $A0000    $A000   $0000  Upper memory begins
  1048575   $FFFFF    $F000   $FFFF  Upper memory ends
To exemplify, let's look 
at some alternative ways we could access
the information about the amount of the base memory. It is very
straight-forward, since in a PC that information is at the fixed
memory location show by the above table. We know this in 
advance.
Using direct memory accessing we could write
  var memsize : word;
  memsize := MemW [$0040:$0013];
  writeln (memsize);
  {.. or ..}
  var memsize : word absolute $0040:$0013;
  writeln (memsize);
If you are not familiar with the true meaning of pointers, they may
feel confusing, but what they basically are is just what the name
indicates, pointers to memory locations. Study the following
example.
  var memsizePtr : ^word;           { A pointer to a word }
  begin
    memsizePtr := ptr ($40, $13);   { Assign the pointer a value }
    writeln (memsizePtr^);          { Write what is in the address }
  end.                              { that was pointed to }
This was relatively simple, since we knew in advance the location 
of
the information. Lets look at a case where we do not know that.
Consider
  var x : word;
  begin
    x := 1223;
    writeln (x);
  end.
We have a variable x somewhere in the memory, and we can refer 
to it
without ever needing to know where the variable actually is in the
memory. But how does one find out if one for some reason wants 
or
needs to know?
  var x       : word;
      Segment : word;
      Offset  : word;
      y       : ^word;
  begin
    x := 1223;
    writeln (x);
    Segment := Seg(x);
    Offset  := Ofs(x);
    writeln ('Variable x is at $', HEXFN(Segment), ':$', HEXFN
(Offset));
    {... one test to ensure that the value really is in there ...}
    writeln (MemW [Segment:Offset]);
    {... another test to demonstrate that the value really is in there ...}
    y := Addr(x);
    writeln (y^);
  end.
Next consider
  var xPtr    : ^word;
      Segment : word;
      Offset  : word;
      yPtr    : ^word;
  begin
    xPtr^ := 1223;
    writeln (xPtr^);
    Segment := Seg(xPtr^);
    Offset  := Ofs(xPtr^);
    writeln ('$', HEXFN(Segment), ':$', HEXFN(Offset));
    {... a test to ensure that the value really is in there ...}
    yPtr := Ptr (Segment, Offset);
    writeln (yPtr^);
  end.
A further aspect of pointers is that you can utilize them to put a
variables onto the heap instead of the data segment so that you
won't run so easily out of space.
  var xPtr : ^word;
  begin
    { Put it onto the heap }
    New (xPtr);
    xPtr^ := 1223;
    writeln (xPtr^);
    { Get rid of it }
    Dispose (xPtr); xPtr := nil;
    readln;
  end.
Let us return to the addressing. The formulas for converting 
between
the addresses (sent in by Duncan Murdoch) are
  Physical := longint(segment)*16 + offset;
  {}
  Segment  := Physical div 16;
  Offset   := Physical mod 16; { This gives the normalized form }
There are multiple Segment:Offset pairs that refer to the same
address, e.g. $0000:$0413 and $0040:$0013. The normalized 
addresses,
with the offset in the range of 0 to $F, are, however, unique. An
example $0041:$0003.
 

 Contents

На первую страницу

Rambler's Top100 Rambler's Top100
PROext: Top 1000

(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz