BackbuttonStrings

 

There are two implementations for an MCP String Variable.

In Algol, a String Variable declared as a Local Variable to a Procedure is implemented by allocating a String Variable from the Program's Strings Pool, which is a String Array located in the base of the D[2] Stack. The MCP provides the  GetStringArea, GetStringPoolSize and ResetStringPoolSize Intrinsic functions to manage the Strings Pool. This method requires 2 Stack Cells for a String Variable.

In Algol, a String Variable declared as a local variable in a Structure Block is implemented by calling ArrayDec. This method requires 3 Stack Cells for a String Variable.

Strings allocated from the Strings Pool

A String Variable allocated from the Strings Pool is described by a Copy Descriptor to an Ebcdic Array containing the String Data and above it, a Single Precision Operand which contains the current logical length of the String Data.

002C (02,0016) 0 000000 000000     
002B (02,0015) C F20000 001DF9 HEXSTRING   (Hex variable) Absent-copy,
                               ASD=00EFCF, Hex, Length=264 (Unreferenced olay space)    
002A (02,0014) 0 000000 000000 
0029 (02,0013) C D40000 001D6D ASCIISTRING (ASCII variable) Absent-copy,
                               ASD=00EB6E, EBCDIC, Length=132 (Unreferenced olay space)
0028 (02,0012) 0 000000 000000 
0027 (02,0011) C B40000 001E27 EBCDICSTRING (EBCDIC variable) Absent-copy,
                               ASD=00F13D, EBCDIC, Length=132 (Unreferenced olay space)

String Variables are managed by the GetStringArea, GetStringPoolSize ResetStringPoolSize Intrinsic functions.

 A maximum of 500 String variables can be allocated using these String Intrinsics. (Note: This limit applies only to String Variables, and does not include Strings in String Arrays which are created using ArrayDec, nor to String Variables allocated in a Structure Block).

Although the Algol Compiler differentiates between ASCII and EBCDIC Strings, the architecture does not.

The declaration of GetStringArea is in the MCP at 10810000, 

			WORD PROCEDURE GETSTRINGAREA;

It returns an Untouched Copy Descriptor to an element in the String Pool of the current Stack.

This is an example of a call to GetStringArea to declare a String Variable.

			CodeSegment.MKSN;
			CodeSegment.NMC1(D1_Stack.MCPIntrinsicSDI(GetStringAreaV));
			CodeSegment.ENTR;
			CodeSegment.ZERO;

The Compiler creates a Hex String by setting the Character Size of the Untouched Descriptor to HexV.

			CodeSegment.MKSN;
			CodeSegment.NMC1(D1_Stack.MCPIntrinsicSDI(GetStringAreaV));
			CodeSegment.ENTR;
			CodeSegment.SE4C;
			CodeSegment.ZERO;

Since a String Variable is represented by a Copy Descriptor, there is no BlockExit action required.

However, if String Variables are not returned to the Strings Pool upon exiting a procedure, then they can no longer be reused and eventually the Strings Pool will be exceeded.

The GetStringPoolSize and ResetStringPoolSize Intrinsics are provided to manage the Strings Pool as a Stack.

In a Block which declares a String Variable, the Compiler allocates a variable called a 'String Pool Size Location', and calls GetStringPoolSize to initialize it to the current Strings Pool Top.

The Compiler then allocates String Variables by calling GetStringArea.

The Compiler generates an Epilog Procedure for the Block, and calls ResetStringPoolSize with the previously saved String Pool Top, thereby releasing any String variables declared in the Block.

The declaration of GetStringPoolSize is in the MCP at 10820000, 

			REAL PROCEDURE GETSTRINGPOOLSIZE;

The declaration of ResetStringPoolSize is in the MCP at 10830000, 

			PROCEDURE RESETSTRINGPOOLSIZE(S);
 			VALUE S; REAL S;

This code was produced by the Algol Compiler.

       PROCEDURE P;                                           
(02,0002) = P     
        Begin                                                         
          String S;                                                  
(03,0002) = STRING POOL SIZE LOCATION
(03,0003) = S     
(03,0004) = S.LENGTH    
         End;                                                                
    (01,0005) = RESETSTRINGPOOLSIZE     
                        0004:0000:1  MKSN               DF 
                        0004:0000:2  NAMC  (01,0005)    6005  RESETSTRINGPOOLSIZE  
                        0004:0000:4  VALC  (03,0002)    3002     
                        0004:0001:0  ENTR               AB 
                        0004:0001:1  EXIT               A3 
**********************  STACK BUILDING CODE FOR LEVEL 03  *******************************
(03,0002)  
    (01,0006) = GETSTRINGPOOLSIZE 
                        0004:0001:2  MKSN               DF 
                        0004:0001:3  NAMC  (01,0006)    6006  GETSTRINGPOOLSIZE    
                        0004:0001:5  ENTR               AB 
(03,0003)   = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    (01,0007) = GETSTRINGAREA     
                        0004:0002:0  MKSN               DF 
                        0004:0002:1  NAMC  (01,0007)    6007  GETSTRINGAREA  
                        0004:0002:3  ENTR               AB 
                        0004:0002:4  ZERO               B0 
                        0004:0002:5  BRUN      0004:3   A26004   
                        0004:0003:2  MKSN               DF 
                        0004:0003:3  NAMC  (01,0005)    6005  RESETSTRINGPOOLSIZE  
                        0004:0003:5  VALC  (03,0002)    3002     
                        0004:0004:1  ENTR               AB 
                        0004:0004:2  EXIT               A3 
(03,0005) = STRING POOL EPILOG PCW  
                        0004:0004:3  MPCW               BF 
                        0004:0005         0004:0003:2   000400312004   
                        0004:0006:0  PUSH               B4 
                        0004:0006:1  LT48               BE 
                        0004:0007                       800000200000
                        0004:0008:0  LT8   6            B206     
                        0004:0008:2  STAG               95B4     
                        0004:0008:4  BRUN      0000:1   A22000   

Strings allocated by ArrayDec

A String Variable allocated using ArrayDec occupies 3 Stack Cells.

At the lowest address is a Tag 4 String Marker, followed by an Untouched_DD MOM Descriptor for the EBCDIC Array which contains the String's Data, and finally a Single Precision Operand which contains the current logical Length of the String Data.

The Stack Cells are created by calling the MCP ArrayDec Intrinsic.

001A (02,0004)  C E00000 001F97  T1           (Structure block)  Present-mom, ASD=00FCBF, Length=26   
        0(0000) 3 08CD00 160000 1 80FCBF 000000 0 000000 000000 0 000000 000001 0 000000 000001 2 
							000000 000001 2 000000 000001     
        7(0007) 6 000000 000000 4 000FFF EC0000 5 040008 400000 0 000000 000000 C E00000 001E50 
             0(0000) 0 000000 000000 Thru 10(000A)        

The declaration of ArrayDec is in the MCP at 4709950, 

PROCEDURE ARRAYDEC (SIRW_TO_MOM,NO_OF_DIMS,TYPE_INFO); 
 VALUE SIRW_TO_MOM, NO_OF_DIMS, TYPE_INFO; 
 REAL NO_OF_DIMS; 
 WORD SIRW_TO_MOM, TYPE_INFO; 

ArrayDec is declared as a PROCEDURE and behaves as one for Strings. The Compiler is responsible for allocating the Stack Cells. ArrayDec stores the String Marker at the Stack Cell below the SIRW_TO_MOM, the Ebcdic String Array Untouched_DD at the SIRW_TO_MOM, and it leaves the Integer in the Stack Cell above the SIRW_TO_MOM as it was allocated by the Compiler.

ArrayDec deletes the Top 2 Stack Items passed under it's MSCW, which are the Maximum String Length and the Initial String Length hidden dimension. These items are used by ArrayDec to create the String Marker.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  First store the MOM template.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
WORD VIA MOM_REF := IDD;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 Now address the SIW slot below the MOM and store the SIW.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
MOM_REF.SIRWDELTAF := * - 1;
WORD VIA MOM_REF :=
    0 & THIS_STACK [HIST_TOP-1] STRINGMAXLENGTHF
      & FAULTSTRINGMARK         FAULTMARKF
      & SIW                     TAG;
STRINGMAXLENGTHF = [39:20] @ 10802800

This code was produced by the Algol Compiler.

Type Structure Block T_1;                                           
 (02,0002) = STRUCTURE BLOCK PCW     
 (02,0003) = T_1   
                  Begin                                                                       
 (03,0002) = T_1 SELF DESCRIPTOR     
                    String S;                                                          
(03,0003) = STRING MARKER     
(03,0004) = S     
(03,0005) = S.LENGTH    
                     0003:0000:1  LT8   132          B284     
                     0003:0000:3  LT16  65534        B3FFFE   
 (01,0004) = ARRAYDEC    
                     0003:0001:0  MKSN               DF 
                     0003:0001:1  NAMC  (01,0004)    6004  ARRAYDEC 
                     0003:0001:3  NAMC  (03,0004)    7004     
                     0003:0001:5  STFF               AF 
                     0003:0002:0  ONE                B1 
                     0003:0002:1  LT8   4            B204     
                     0003:0002:3  BSET  41           9629     
                     0003:0002:5  ENTR               AB 
                  End;                             

The use of the Strings Pool takes advantage of the Stack to dynamically allocate and delete String Variables without the cost of repeated Initial Presence Bit action.

A Structure Block is a permanent Procedure instance, hence the static allocation of a String Variable.

MCP Strings Support

In addition to ArrayDec and the String Pool functions, the MCP provides support for the automatic resizing of the String as it expands in size.

When modifying a String, the compiler generates the same machine code used in an Algol REPLACE statement.

For a normal array, if the boundary of the destination array is reached before the operator has completed, a STRING PROTECT (SEG ARRAY) error is reported.

However, when the fault occurs with a String, the MCP resizes the String Data Array, and resumes the interrupted operator.

The fault is handled by calling HWIVP_DESTINATION_BOUNDARY at 11110800,

IF GETSPACEARRAY(P2)
  THEN
    BEGIN
      IF STRINGSTRETCHER (POINTER (P2),
                          MIN ((2 * (DESCRIPTORSIZE (P2, TRUE) DIV
                                     IF CHARSIZE (P2) = HEXV
                                       THEN HEXADESPERWORD
                                       ELSE BYTESPERWORD    )),
                               1000)              * BITS_PER_WORD,
                          INSET (SPACEUSAGE (P2), SEGSEG_SET))
        THEN
          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
          % THE STRING WAS STRETCHED. THEREFORE RESUME.
          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
          RESUME (P1);
    END;

Strings are allocated by ARRAYDEC, and are therefore a GETSPACEARRAY .

The STRINGSTRETCHER function is at 10840000.

BOOLEAN PROCEDURE STRINGSTRETCHER(DESC, RESIDUE, SEGED);
     VALUE DESC, RESIDUE, SEGED;
     POINTER DESC;
     REAL RESIDUE;
     BOOLEAN SEGED; 
 DESCRIPTION:                                                        
       STRINGSTRETCHER IS CALLED WHEN THERE IS A POSSIBILITY THAT A   
       STRING SHOULD BE STRETCHED.  THE FOLLOWING ACTIONS MAY BE      
       TAKEN:                                                         
                                                                      
       IF THE STRING IS ALREADY SEGMENTED ONE OR MORE SEG_ARRAY_ROW   
       SIZE SEGMENTS ARE ADDED TO THE STRING.                         
       OTHERWISE IF THE STRING IS LESS THAN SEG_ARRAY_ROWSIZE WORDS   
       IT IS EXPANDED  TO A MULTIPLE OF STRING_EXP_INCREMENT WORDS    
       LARGE ENOUUGH TO HOLD LEN+RESIDUE, OR SEG_ARRAY_ROWSIZE.       
       OTHERWISE THE STRING IS TURNED INTO A SEGMENTED STRING.        
. PARAMETERS:                                                         
       DESC:     THE DESTINATION DESCRIPTOR THAT WAS INVOLVED IN THE  
                 ARRAY INTERRUPT.                                     
       RESIDUE:  THE NUMBER OF BITS TO BE TRANSFERED TO COMPLETE THE  
                 INTERRUPTED OPERATOR.                                
       SEGED:    TRUE IFF THE DESTINATION DESCRIPTOR POINTS AT A      
                 "SEGSEG".                                            
. RESULTS:                                                            
       STRINGSTRETCHER RETURNS FALSE IF THE DESTINATION DESCRIPTOR IS 
       NOT A STRING DESCRIPTOR OR IF COMPLETION OF THE INTERRUPTED    
       OPERATION WOULD EXCEED THE MAX SIZE FOR THE DESTINATION STRING.
       OTHERWISE:                                                     
       RETURNS TRUE IF THE STRING IS STRETCHED AND NOT SEGMENTED.     
       RETURNS BOOLEAN(3) IF THE STRING IS STRETCHED AND IS NOW       
       SEGMENTED.                                                     
. ASSUMPTIONS:                                                        
       WE MUST NOT LOSE CONTROL OR BUZZ LOCKS USED BY SYSTEMSTATUS.   
       SEE COMMENT AT START OF HARDWAREINTERRUPT PROCEDURES.          
. SIDE EFFECTS:                                                       
       NONE.                                                          
. LOCKS:                                                              
       NONE.                                                          

The function checks if the Array is part of a String, by checking the Tag 4 Word located below the Descriptor.

     TWORD:= STACKDESC[STKLOC-1];
     IF (TWORD.TAG EQL SIW) AND
        (TWORD.FAULTMARKF EQL FAULTSTRINGMARK) AND
        (TWORD.STRINGMAXLENGTHF*CS - LEN GEQ RESIDUE) THEN
          BEGIN
          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
          % THIS STRING MAY BE STRETCHED AS IT HAS NOT REACHED ITS
          % MAXIMUM LENGTH.
          %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 

Passing Strings By Reference

To pass a String By Reference, the Algol Compiler generates an SIRW for both the Length and the Descriptor.

String S;    
(03,0003) = STRING MARKER     
(03,0004) = S     
(03,0005) = S.LENGTH    

   0003:0005:1  NAMC  (03,0004)    7004     
   0003:0005:3  STFF               AF 
   0003:0005:4  NAMC  (03,0005)    7005     
   0003:0006:0  STFF               AF