Previous Table of Contents Next


Listing 5.30. An example of bitwise operators.

  program fig30; uses wconv;

    { visual demonstrator of effects of all bitwise evaluators,
      actually, a good tutorial/flash card program for learning
      these operators. function writebinary(inbyte: byte):string;
      is from wconv, a utility unit I have written for writing
      values in different common bases for my personal use. Code not
      included because it does not further the topic of this program.
      Such a function may be created easily with the knowledge of
      base conversions. }

    var
      option, num1, num2: byte;

    procedure processinfo(option, num1, num2: byte);
      begin
        writeln(writebinary(num1):23);
        case option of
          1: write(‘SHL’);
          2: write(‘SHR’);
          3: write(‘AND’);
          4: write(‘ OR’);
          5: write(‘XOR’);
        end;
        { no point in writing out bits for 2nd number if SHL or SHR }
        if option in [1..2] then
          writeln(num2:10)
        else
          writeln(writebinary(num2):20);
        writeln(‘======================’);
        case option of
        1: writeln(writebinary(num1 shl num2):23);
        2: writeln(writebinary(num1 shr num2):23);
        3: writeln(writebinary(num1 and num2):23);
        4: writeln(writebinary(num1 or num2):23);
        5: writeln(writebinary(num1 xor num2):23);
      end;
    end;

   begin
    option := 10;
    while option <> 6 do
      begin
        writeln;writeln;
        writeln(‘Enter a number from the list below:’);
        writeln(‘1) SHL 2) SHR 3) AND 4) OR 5) XOR 6) QUT’);
        write(‘Enter an option [1-6]: ’);
        readln(option);
        if option <> 6 then
          begin
            write(‘Enter first number: ’);
            readln(num1);
            write(‘Enter second number: ’);
            readln(num2);
            writeln;
            processinfo(option, num1, num2);
          end;
     end;
end.

In addition, functions called lo, hi, and swap are provided. In a series of bits, they can be divided in half. The more significant bits are referred to as the high order, and the least significant bits are referred to as the low order. lo() returns the low order of the argument given, hi() returns the high order of the argument given, and swap() returns the argument with the high and low orders swapped.

5.2.8. Dynamic Memory Allocation

The PCs with the 8088 class CPUs could only deal with 64 KB of data (declared variables) at once because of the CPUs’ limitations. Of course, when this computer was created, it was realized that to have 1024 KB of usable memory in it, along with the capability of accessing all this memory and not only 64 KB of it, that some way had to be devised to do this. Machine could handle only a maximum of a 16-bit address and 64 KB of data at a time.

Ultimately, it was decided for this computer to use a segment:offset combination in addressing memory, resulting in a 20-bit system for addressing memory in the DOS PC system. Also, because the limitation in memory that the CPU could handle was there, it was determined that a 4-byte address in memory could be created in order to redirect the CPU to a position in memory to find a variable or point essentially to the position in memory that holds this variable at a particular moment.

A pointer, which was described earlier, is the main means for accessing this extra memory. This 4-byte address points to a predescribed data type at a particular position in memory. Eventually, with this system of addressing memory, where 64 KB of memory was directly accessible, and the rest of the free memory up to 640 KB was referred to by pointers, special terminology was devised to refer to these portions. The portion of memory directly accessed could be referred to as the data area, and the rest of the memory accessible by pointers could be referred to as the heap. These elements are still referred to in that manner today with a 16-bit compiler because of the concern for backward compatibility.

Turbo Pascal uses a system such as this to access the other part of the 640 KB of conventional memory. In the sense that pointers can be used to dynamically place information in the heap, this section is referred to as dynamic memory allocation. This is essentially the creation, destruction, and readdressing of memory allocation at runtime instead of compile time, in which the directly accessible memory is addressed.

There are many reasons you might use pointer-based structures over static based structures. One, which has already been alluded to, is the ability to create variable data structures in excess of 64 KB. Two is the ability to dynamically allocate variables, if they are large variables that are temporarily used at one time in the program to conserve memory. Three is the ability to create pointer-based structures in many different forms, such as linear linked lists and tree-based structures, to express some algorithm that would be incredibly inefficient in other methods. Four is the sheer dynamic nature of pointer-based structures—for example, the ability to insert a new variable in any position of the structure without “shuffling” the contents currently in an array-based structure.

The means to access and use pointer-based structures is described next, as well as addressing values in memory for variables, procedures, and functions. A special exit procedure developed in Turbo Pascal called exitproc is also described.


Previous Table of Contents Next