BRANCH RESOLUTION VIA BACKWARD SYMBOLIC EXECUTION

Abstract: Possible values for a computed destination address of an execution transfer instruction are found by a backward search through a flowgraph of a program. During the search, a symbolic expression for the destination address is successively modified to reflect the effect of each prior instruction until the symbolic expression represents an absolute or program-counter relative address, or until the search can no longer continue. The search can no longer continue, for example, when an instruction is reached that affects the value of the expression in an indefinite way. When backward symbolic execution reaches the entry point of a block in the flowgraph, backward symbolic execution proceeds backward to each predecessor block that has not already been examined for the execution transfer instruction. Therefore multiple definite values as well as a value of "unknown" may be found for a computed destination address. Preferably backward symbolic execution is performed while constructing the flowgraph, in order to find the locations of additional instructions. As additional instructions are found, new blocks and new paths between blocks are added to the flowgraph. Backward symbolic execution is repeated when the new paths may provide additional values for the computed destination addresses.

Description: BRANCH RESOLUTION VIA BACKWARD SYMBOLIC EXECUTION BACKGROUND OF THE INVENTION 1. Field of the Invention The present invention relateε to the translation of program code for a digital computer, and more particularly to the translation of program code from one language to another in cases where the location of all of the program code to be translated is not known until the program code is actually executed. 2. Description of the Background Art Computer language translation programs are well known for translating high-level languages such as Pascal, Fortran, Cobol, PL/I or c into machine language. For these languages, programs are coded in an English- like style. A language translation program called a compiler reads the high level language program (called the source program) and translates it into a machine language program (called the object program). One major advantage of high level languages, besides the ease with which they can express algorithms, is their machine independence. They hide the specifics of the hardware machine and instruction set. Nonetheless, there are a number of applications where machine language programming is desirable. To increase the execution speed of a program, it is often desirable to write code for repetitively executed procedures in machine language to minimize the number of machine cycles that are needed to execute the procedures. Machine language programming is also required in many computer systems to directly control specific hardware features of a particular computer. For example, the parts of an operating system that manage memory and input/output devices are often written in machine language. Machine language programming is usually written in assembly language code instead of binary code. Assembly language permits the programmer to specify machine operations using symbolic names for memory locations and instructions. A program called an assembler translates the assembly language program into binary machine code. The assembler does all of the work of remembering the values of symbols and the addresses of data elements. However, unlike the high level language, each assembly language instruction corresponds to exactly one machine instruction. More recently there has arisen a need to translate machine language for one kind of computer to machine language for another kind of computer. Thiε need has arisen due to rapid advances in computer hardware that have made new computer architectures more cost effective. In particular, for more than a decade most high performance computers for general purpose applications used a "complex instruction set architecture" (CISC) characterized by having a large number of instructions in the instruction set, often including variable-length instructions and memory-to-memory instructions with complex memory accessing modes. The VAX ".instruction set is a primary example of CISC and employs instructions having one to two byte opcodes plus from zero to six operand specifiers, where each operand specifier, is from one byte to eighteen bytes in length. The size of the operand specifier depends upon the addressing mode, size of displacement (byte, word or longword), etc. The first byte of the operand specifier describes the addressing mode for that operand, while the opcode defines the number of operands: zero to six. The opcode itself, however, does not always determine the total length of the instruction, because many opcodes can be used with operand specifiers of different lengths. Another characteristic of the VAX instruction set is the use of byte or byte string memory references, in addition to quadword or longword references; that is, a memory reference may be of a length variable from one byte to multiple words, including unaligned byte references. The CISC architecture provided compactness of code, and also made assembly language programming easier. When the central processor units (CPU) were much faster than memory, it was advantageous to do more work per instruction, because otherwise the CPU would spend an inordinate amount of time waiting for the memory to deliver instructions. Recently, however, advances in memory speed as well as techniques such as on-chip cache and hierarchical cache have eliminated the primary advantages of the CISC architecture. Therefore the selection of the instruction architecture is now dictated by the required complexity of the CPU for maximizing execution speed at reasonable cost. These considerations indicate that a reduced instruction set architecture (RISC) has superior performance and cost advantages. Reduced instruction set or RISC processors are characterized by a smaller number of instructions which are simple to decode, and by the requirement that all arithmetic/logic operations are performed register-to- register. Another feature is that complex memory accesses are not permitted; all memory accesses are register load/store operations, and there are only a small number of relatively simple addressing modes, i.e., only a few ways of specifying operand addresses. Instructions are of only one length, and memory accesses are of a standard data width, usually aligned. Instruction execution is of the direct hardwired type, as distinct from microcoding. There is a fixed instruction cycle time, and the instructions are defined to be relatively simple so that they all execute in one short cycle (on average, since pipelining will spread the actual execution over several cycles). Unfortunately there is a vast amount of computer software already written for established instruction architectures, and much of that software includes machine language programming that did not originate from the compilation of a high-level language. In these cases the software can not be "ported" to the new computer architecture by the usual method of re-compiling the source code using a compiler written for the new instruction architecture. In some cases, assembly language code exists for the machine language programming of existing computer software. Therefore it should be possible to write a translator program for translating each assembly language instruction into one or more machine instructions in the new instruction architecture that perform the same basic function. The practicality of such a direct translation is dependent upon the compatibility of the new instruction architecture. For translating CISC code including VAX instructions to RISC code, for example, the practicality of the translation is improved significantly by innovations in the RISC CPU hardware and the RISC instruction set, aε further described in Richard L. Sites and Richard T. Witek, "Branch Prediction in High-Performance Processor," U.S. application Serial No. 07/547,589 filed June 29, 1990, herein- incorporated by reference. In many cases existing computer software inpludes binary machine language code for which there does not exist a complete or coherent set of high-level or assembly language source code. This presents a very difficult problem of locating all of the binary machine code to translate. In the usual case a portion of the SUBSTITUTE SHEET binary machine code in a program cannot be found prior to execution time because the code includes at least one execution transfer instruction, such as a "Jump" or "Call" instruction, having a computed destination address. At execution time, the destination address is computed, and execution is transferred from the instruction to the "missing" code. In more unusual cases, some of the binary machine code in a program is not created until execution time. These unusual cases are typically due to poor programming techniques, although code is often created at execution time for security purposes, for example, as part of a "license check" routine. The "license check" routine, for example, writes a sequence of instructions to a scratch memory area and then executes the sequence of instructions. To circumvent the licensing routine, one must discern the mode of operation of the routine from the sequence of instructions written to the scratch area. But the sequence of instructions is absent from the usual print-out or dump of the program, because the sequence of instructions does not exist until execution time. When there is a problem of locating all of the machine code in an original program, the code has been interpreted at execution time. The translation process of the interpreter is similar to an assembly language translator, but interpretation at execution time is about two orders of magnitude slower than execution of translated code, due to the fact that a multiplicity of instructions in the interpreter program must be executed to interpret each machine instruction. To permit the use of an incomplete translation, an interpreter program, a copy of the original program, and address conversion information is provided together with the translated code when porting the original program to a CPU using the new instruction architecture. When execution of the translated code reaches a point corresponding to an execution transfer in the original program to untranslated code, the CPU transfers execution instead to the interpreter program to interpret the untranslated code in the original program. The interpreter successively translates each untranslated machine instruction into one or more machine instructions for the new architecture and executes them. The interpreter uses the address conversion information to transfer execution back to the translated program at an appropriate time. The presence of untranslated code, however, has a substantial impact on performance unless almost all of the instructions can be located and translated prior to execution time. SUMMARY OF THE INVENTION As introduced above, program code cannot be located in the usual case because the code includes an execution transfer instruction having a computed destination address. In accordance with an important aspect of the invention, the computed destination address is resolved by a backward search from the execution transfer instruction through the program to find at least one prior instruction which is used to resolve the computed destination address to an address value that is fixed with respect to the addresses of the instructions in the program. Therefore, at least one additional instruction for the program is found at the address value to which the computed destination address is resolved. Preferably a plurality of prior instructions are used to resolve the computed destination address by a process of backward symbolic execution in which the destination address for the execution transfer instruction is represented by a symbolic expression, and the expression is successively modified to reflect the effect of each prior instruction. For example, suppose the execution transfer instruction is "JMP R6+4" which transfers execution to the absolute address computed by adding four to the contents of a general purpose register R6. The computed destination address, for example, is represented symbolically as "R6+4". Suppose that in the backward direction through the program, the next instruction that references R6 is "MOVAB 4(R5),R6" which adds 4 to the contents of a general purpose register R5 and puts the sum into R6. Then the symbolic expression "R6+4" is pushed back through the prior "MOVAB 4(R5),R6" instruction to obtain the modified expression "R5+8". The modified expression has the εame value before the prior instruction as the symbolic expression has after the prior instruction. The process of backward symbolic execution continues until either the computed destination address is resolved to an absolute or image-relative address, or a prior instruction iε reached which affectε the value of the computed destination address but for which backward symbolic execution is not permitted. Backward symbolic execution is not permitted, for example, for certain instructions (such as XORB2 Rl,R2) for which backward symbolic execution is unable or unlikely to resolve the computed destination address. In this case it is convenient to reduce the computed destination address to a symbolic value of "UNKNOWN" to indicate the possibility of missing code. Permitting symbolic execution for only a limited set of instructionε (εuch aε additionε, subtractions, loads, and stores involving general purpose registers), however, allows the resolution of a large fraction of the computed destination addresses found in typical programs. Preferably backward symbolic execution to resolve computed destination addresses is performed while constructing a flow graph of the instructions found for the program. The flow graph includes execution paths interconnecting basic blocks of the instructions found for the program. Each basic block is a sequence of contiguous instructions that has a single known entry point at the beginning of the basic block and a single exit point at the end of the block. Execution is transferred only to the beginnings of the basic blocks, and execution iε tranεferred only from the ends of the basic blocks. When backward symbolic execution for the computed destination addresε of a given execution tranεfer instruction reaches the entry point of a basic block, backward symbolic execution proceeds backward to each predecessor block that has not already been examined for the given execution transfer instruction. This last qualification avoids infinite loops in the backward symbolic execution. For thiε purpose, for example, an "epoch number" is incremented each time that backward symbolic execution is begun for a different given execution tranεfer instruction having a computed destination address, and that value of the epoch number is assigned to an epoch number attribute for each block when the backward symbolic execution is performed through each block. Because backward symbolic execution may proceed from the entry point of one basic block to the ends of a plurality of other blocks, it is possible that the computed destination address of a given execution transfer instruction may be resolved to a plurality of different values. It is also poεsible that the process of backward symbolic execution will cause a series of contiguous instructions identified as a basic block to be re-identified as two basic blocks. This happens when a computed destination address is resolved to be an addreεε in a basic block of code other than the address of the first instruction in that basic block of code. Whenever a new value for a computed destination address is resolved, either additional instructions are located or a new execution transfer path is discovered to previously located instructions. Whenever a new execution transfer path is diεcovered to a previouεly located instruction, it is possible that backward symbolic execution from the previously located instruction along the new path may resolve one or more additional values for a computed destination address in an execution transfer inεtruction following the previouεly located instruction. Therefore backward symbolic execution iε repeated in this case. The repetition of backward symbolic execution may locate additional execution transfer paths to previously located instructions causing still further repetition of backward symbolic execution, but eventually no additional execution transfer paths will be found, so that the process terminates. BRIEF DESCRIPTION OF THE DRAWINGS Other objects and advantages of the invention will become apparent upon reading the following detailed description and upon reference to the drawings in which: FIG. 1 is a block diagram of a CISC digital computer system having a pipelined processing unit .especially constructed for processing complex instructions; FIG. 2 is a diagram showing the state of the pipelined processing unit of FIG. 1 when simultaneously performing different tasks for a number of instructions; FIG. 3 is a diagram showing the preferred format of a variable length instruction from the complex instruction set; FIG. 4 is a diagram of a particular variable length instruction for performing an addition between longwords; FIG. 5 is a table showing the decoding of the mode information in the first byte of a specifier; FIG. 6 is a block diagram of a RISC digital computer system; FIG. 7 is a block diagram of preferred instruction formats for instructions in the RISC instruction set; FIG. 8 is a block diagram of a translator having an analyzer and a RISC code generator for translating an original CISC program to a translated program having RISC instructions; I . 9 is a block diagram showing data and program input and data output from the RISC computer when execution is shared between a partial RISC translation of an original CISC program and an interpreter for interpreting untranslated portions of the original CISC program; FIG. 10 is a flowchart of steps in a RISC code generator of FIG. 8 that call the interpreter used in FIG. 9; FIG. 11 is a flowchart of the interpreter and its operation when execution is shared with the partial RISC translation as shown in FIG. 9; SUBSTITUTE SHEET FIG. 12 is a flowchart of an address checking routine that determines when execution is passed from the interpreter to the partial RISC translation; FIG. 13 is a flowchart of the operation of the translator of FIG. 8; FIG. 14 is a summary page generated by the translator of FIG. 8 and including a memory map of the original CISC program having been translated; FIG. 15 is a flowgraph of the original CISC program; FIG. 16 is an error-specific flowgraph of the original CISC program; FIG. 17 is block diagram of data structures used by the analyzer of the translator for automatic generation of flowgraphs from machine code; FIG. 18 is a flowchart of a procedure used by the analyzer for the automatic generation of flowgraphε from machine code; FIG. 19 is flowchart of a procedure used by the analyzer for investigating paths from execution transfer instructions during the automatic generation of flowgraphs from machine code; FIG. 20 is a flowchart of a procedure used by the analyzer for performing backward symbolic execution in an attempt to find valueε of a computed destination address prior program execution; FIG. 21 is a fixed format representation of a term in a symbolic expression for a destination address that may include a constant displacement, a specified general purpose register, and an indication of direct or indirect memory access; FIG. 22 is a fixed format representation of a term in a symbolic expression for a destination addreεε that may include a constant displacement, a specified general purpose "base" register, a εpecified general purpose "index" register, a constant offset, and an indication of direct or indirect memory access; FIG. 23 is a schematic representation of a flowgraph of a main program routine illustrating an indirect program loop including execution transfer pathε εhown by dashed lines; FIG. 24 is a flowchart of a procedure used in backward symbolic execution for searching a basic block in an attempt to find values for a given symbolic expression; FIG. 25 is a flowchart of a procedure used in backward symbolic execution for pushing a given symbolic expression backward through an instruction in order to modify the symbolic expression so that the modified expression would represent the same value during program execution just prior to execution of the instruction as the given symbolic expression would represent just after execution of the instruction; FIG. 26 is a format for data that could be predetermined for each possible instruction opcode to asεiεt in puεhing symbolic expressions backward through instructions; FIG. 27 is a flowchart of a routine for checking whether the pushing of a symbolic expression through an instruction has converted the expresεion to a form that represents a definite address in the computer program or in the operating system of the computer, and whether that address represents a permissible destination for the transfer of program execution; FIGs. 28 and 29 together compriεe a flowchart of a procedure including three scanning modeε for finding plausible program code in unknown code areas of program memory; FIG. 30 is a flowchart of a general procedure for program conversion and maintenance by iteratively retranslating an original program with the benefit of an execution log file identifying locations of untranslated program code that was interpreted during program execution; FIG. 31 is a flowchart of a procedure for alternately translating and retranslating two mutually 19 The preferred embodiment of the invention is advantageously employed in translating program code for a complex instruction set computer (CISC) to program code for a reduced instruction set computer (RISC). Turning now to the drawings and referring first to FIG. 1, there is εhown a complex inεtruction set digital computer 20 which includes a central processing unit 21, an input/output unit 22, and a main memory 23. Both data and instructions for processing the data are stored in addressable storage locations within the main memory 23. An instruction includes an operation code (opcode) that specifies, in coded form, an operation to be performed by the CPU, and operand specifiers that provide information for locating operands. In a typical CISC instruction architecture, the first byte of each instruction contains the opcode, and the following bytes contain the operand specifiers. The instructions preferably have a variable length, and various types of specifiers can be used with the same opcode, as disclosed in Strecker et al., U.S. Patent 4,241,397 issued December 23, 1980, incorporated herein by reference. The main memory 23 includes a large amount of storage, and therefore it is constructed of inexpensive but relatively slow storage devices such as dynamic random access (DRAM) memory chips. Because the CPU 21 18 dependent programs and testing for convergence in a situation where the two programs cannot be easily merged or translated together at the εame time; FIG. 32 is a block diagram of image information files for two mutually dependent programs and showing linkages between the files; and FIG. 33 iε a flowchart of a procedure which exploits linkages between the information files for two mutually dependent programs in order obtain rapid convergence when the programs are alternately translated and re¬ translated. While the invention is susceptible to various modifications and alternative forms, a specific embodiment thereof has been shown by way of example in the drawings and will be described in detail herein. It should be understood, however, that it is not intended to limit the invention to the particular form disclosed, but on the contrary, the intention is to cover all modifications, equivalents, and alternatives falling within the spirit and scope of the invention as defined by the appended claims. DETAILED DESCRIPTION OF THE PREFERRED EMBODIMENT executes instructions at a faster rate than the access time of the main memory, the CPU includes a memory access unit 24 that keeps a copy of a portion of the data and instructions in a high-speed cache memory of relatively small storage capacity. Usually the CPU obtains the data and instructions that it needs from the cache memory in the memory access unit 24, and when the required instructions or data are not found in the cache memory, the memory access unit accesses the main memory unit 23 to "refill" the cache memory with the required instructions or data. The memory access unit 24 may also include means εuch as a translation buffer for translating "virtual" addresses used in the instructionε to "physical" addresses used in the main memory 23. This technique permits the programmer to reference a "virtual address space" including a greater number of addressable memory locations than are provided in the main memory 23. Therefore the programmer is less constrained by limited storage capacity of the main memory 23. To provide even faster access to data, the instructions may reference a limited number of general purpose registers included in a multi-port register file 25. Some of these general purpose registers may be assigned specific functions, for example, one general purpose regiεter is typically used as a "program counter" and provideε the addreεs of the instruction being decoded when referenced as a source operand or specifies the address of the next instruction to be decoded when referenced aε a destination operand. The execution of an individual instruction is broken down into multiple sub-tasks that are performed by respective pipelined functional units. These pipelined functional units include an instruction buffer 26 for fetching instructions from memory, an instruction decoder 27 for decoding the fetched instructionε, an operand unit 28 for fetching source operands identified by source operand specifiers, an execution unit 29 for performing arithmetic, logic, and special operations upon the source operands to obtain results, and a retire unit 30 for storing the results at memory locations or registers identified by destination operand specifiers. For further details regarding the preferred construction of the complex instruction set digital computer 20, one may refer to Fite et al., "Decoding Multiple Specifiers in a Variable Length Instruction Architecture", U.S. Application Serial No. 07/307,347 filed Feb. 3, 1989, incorporated herein by reference. Turning now to FIG. 2, there is shown a state diagram of the pipelined functional units (26-30 in FIG. 1) for an ideal situation where the digital computer (20 in FIG. 1) executes instructionε at an average rate of one instruction per cycle. Generally, the following steps are performed during the execution of each inεtruction by respective ones of the pipelined units 26- 30: instruction fetch, instruction decode, operand fetch, execute, and store result. One cycle is the minimum time for each functional unit to perform its sub-task. A given functional unit might not perform its sub-task in a single cycle due to contention in the memory access unit (24 in FIG. 1), for example, when the memory access unit is performing a "refill" operation. Moreover, when executing particularly complex instructions, a given functional unit may require more than one cycle to perform its sub- task due to the complexity of the instruction. In any case, by the use of dedicated hardware stages, the steps can be overlapped to some degree in pipelined operation, thereby increasing the total instruction throughput. FIG. 3 depicts a typical instruction 40 that can be procesεed by the central processing unit (CPU) shown in FIG. 1. This instruction corresponds to the VAX variable-length instruction architecture as described in Levy and Eckhouse, Jr., Computer Programming and Architecture. The VAX-11. Digital Equipment Corporation, (1980), incorporated herein by reference. The instruction 40 includes an operation code 41 consisting of either one or two bytes. If the first byte 42 has a value of FD hexadecimal, then it is recognized as a double-byte operation code. Otherwise, the inεtruction decoder (27 in FIG. 1) recognizes the operation code as including only a single byte. The instruction 40 may further include up to six specifiers following the operation code. The operation code indicates how many specifiers are included in the instruction. The specifierε used in connection with any given operation code may have various attributes and different lengths. The attributes of a particular specifier are determined at least in part by an addressing mode in the first byte of the specifier. However, the permissible attributes of the specifier are some times limited by the operation code. Further, for a particular kind of addressing mode known as "immediate addressing," the length of the specifier information is determined by a "data type" specified by the specifier. A specific variable length instruction is shown in FIG. 4. In assembler notation, this instruction iε written as "ADDL3 R0,#4,L Λ 203(R2)". In machine code, the instruction includes eight byteε generally designated 45. The first byte is an operation code of 23 hexadecimal which corresponds to the assembler mnemonic "ADDL3." The operation code indicates that a first longword operand iε to be added to a second longword operand and the longword result is to be stored at a destination. Following the operation code is a "register specifier" having a value of 50 hexadecimal. The hexadecimal digit of 5 denotes that the εpecifier is a register specifier, and the hexadecimal digit 0 indicateε that the εpecified register is the RO general purpose register in the CPU. The register specifier therefore specifies that the first source operand is the content of the general purpose register RO. Following the register specifier is a "short literal specifier" having a value of 04 hexadecimal. The short literal specifier specifieε a value of four for the εecond source operand. Following the short literal specifier .iε the firεt byte of a "complex specifier" that specifies the destination of the addition operation. The hexadecimal digit E indicates a "longword displacement" addressing mode in which the following four bytes are to be interpreted as a thirty-two-bit address displacement to be added to the value of the content of a base regiεter to obtain an addreεε εpecified by the complex εpecifier. The hexadecimal digit 2 indicates that the general purpose register R2 is to be used as the base register. The complex specifier therefore specifies that the sum or result of the longword addition indicated by the operand code is to be stored in memory at an address computed by adding the value of 203 hexadecimal to the content of the general purpose register R2. Turning now to FIG. 5, there is shown a decoding table for decoding the firεt byte of an operand specifier which is not a branch displacement. If the two most significant bits of the first byte of the operand specifier are both zero, then the operand specifier consists of the single first byte, and the six least significant bits of this byte are interpreted or decoded aε specifying a six-bit value referred to as a "short literal." If the first two most significant bits of the first byte of an operand specifier are not zero, and assuming that the byte iε not part of a branch displacement, then the byte is decoded as a particular one of twelve possible register addressing modes relating to a specified one of sixteen general purpose regiεters RO to R15 in the CPU. The most significant four bits of the byte (conεtituting a regiεter mode field) are decoded to indicate the addreεsing mode, and the four least significant bits (constituting a general purpose register address field) are used to addresε a particular one of the sixteen general purpose regiεters. If the register mode field has a hexadecimal value of four, then an "index mode" is specified in which the value of the content of the general purpose register addressed by the register address field is multiplied by the size in bytes of the operand (e.g., by 1, 2, 4, 8 or 16 for respective byte, word, longword, quadword or octaword data types) and the sum iε included as a term in the addreεε computation performed for an immediately following complex specifier; the next byte must have a register mode field with a value of 6 to F hexadecimal, and a register address field which addresseε a base register for the complex specifier. If the register mode field has a hexadecimal value of five, then the specifier is a "register specifier" in which the operand value is found in the general purpose register indicated by the register address field or, if the specifier is for the deεtination of the inεtruction, then the specifier specifies that the result is to be stored in the general purpose register indicated by the register address field. For each of register modes 6, 7 and 8, the designated register contains the memory address for the operand. For a source operand, the operand value is read from this memory address, and for a destination operand, the result is written to this memory address. In mode 6 the designated register contains the addreεs of the operand. In register mode 7 the content of the designated general purpose register is first decremented before computation of the address; in mode 8 the content of the designated general purpose register is incremented after the regiεter is used to compute the address. Register mode 9 is similar to regiεter mode 8, except that the content of the designated general purpose register specifies the address in memory at which the operand address will be found rather than the operand itself. Modes 10 through 15 are various kinds of "displacement modes." In a displacement mode a displacement value, which may comprise a byte, word, or longword in modes 10, 12 and 14 respectively, is added to the content of the designated general purpose register to obtain the operand address. The operand is determined in a similar faεhion in modeε 11, 13 and 15 except that the sum of the displacement value and the content of the general purpose register identifies a memory address at which the addresε of the operand can be found. In modes 8 through 15, the register addreεε field of the first byte of the operand specifier can designate any of the general purpose registers, including register R15 which is the program counter. For modes 8 and 9, if the program counter is addressed, the value of the program counter itself is incremented which causes program execution to jump over operand data or an operand address dispoεed in the instruction stream. In mode 8, this special case is known as an "immediate" addressing mode, and for mode 9 it is known as an "absolute" addressing mode. Specifically, when modes 8 and 9 are decoded for any of the general purpose registerε 0 through 14, the next specifier or the next operation code appears immediately following the byte designating the mode and the general purpose register. For the immediate mode, however, a number of bytes of the immediate data appear and the number of bytes iε determined by the specifier's datatype. Because of the variety and complexity of the VAX variable-length instructions, the digital computer 20 of FIG. 1 is very complex to achieve performance approaching the ideal of one VAX variable-length instruction executed per cycle. Recent advances in semiconductor processing technology and memory architecture, however, have made it possible to fabricate a single-chip central processing unit having comparable performance when executing only simple instructions. To achieve comparable performance, the so-called "reduced instruction set computer" (RISC) executes simple instructionε at a rate εubεtantially in exceεs of one instruction per cycle. This performance is obtained with minimum hardware complexity by imposing the requirement that all arithmetic/logic operations are performed register-to-regiεter. In addition, complex memory accesses are not permitted; all memory accesseε are regiεter load/εtore operationε, and there are only a ε all number of relatively εimple addressing modes, i.e., only a few ways of specifying operand addresseε. Instructions are of only one length, and memory accesseε are of a εtandard data width, usually aligned. Instruction execution iε of the direct hardwired type, as distinct from microcoding. Turning now to FIG. 6, there is shown a block diagram of a reduced instruction set (RISC) computer 50. The RISC computer 50 includes a central proceεεing unit 51, an input/output unit 52, and a main memory 53. The central processing unit 51 includes a memory access unit 54, register file 55, and a number of functional units including an instruction unit 56, an addressing unit 57, an integer and logic execution unit 58, and a floating point execution unit 59. Because all arithmetic/logic operationε are performed register-to-register, the execution unitε 58, 59 do not directly acceεε the memory unit 54. Memory-to-register load operations and register-to-memory store operations are performed by the addressing unit 57. To execute instructionε at a rate substantially in excess of one per cycle, the instruction unit 56 can fetch and decode at least two instructionε εimultaneously when resources are available, and the addresεing unit 57, the integer and logic execution unit 58, and the floating point execution unit 59 can execute three different instructions simultaneously. In a preferred implementation, for example, two instructions can be decoded and issued simultaneouεly when one inεtruction iε from Column A and the εecond instruction iε from Column B: Column A Column B Integer Operate Floating Operate Floating Load/Store Integer Load/Store Floating Branch Integer Branch JSR For further details regarding the RISC computer 50 of FIG. 6, one may refer to the above-mentioned Richard L. Sites and Richard T. Witek, "Branch Prediction in High-Performance Proceεεor," U.S. application Serial No. 07/547,589 filed June 29, 1990, herein incorporated by reference. Referring to Figure 7, there are shown the preferred formats of the various types of instructions of the RISC instruction set executed by the computer 50 of FIG. 6. Each instruction has a fixed length of 32 bitε. A memory instruction 70 containε a 6-bit opcode in bitε <31:26>, two 5-bit register address fields Ra and Rb in bits <25:21> and <20:16>, and a 16-bit εigned diεplacement in bits <15:0>. This instruction is used to transfer data between the register file and memory, to load an effective addresε to a register in the register file, and for subroutine jumps. The displacement field <15:0> is a byte offset; it is sign-extended and added to the contents of register Rb to form a virtual address. The virtual addresε iε uεed aε a memory load/store address or a reεult value depending upon the εpecific instruction. . A branch instruction 71 includeε a 6-bit opcode in bits <31:26>, a 5-bit addresε field in bitε <25:21>, and a 21-bit εigned branch displacement in bits <20:0>. The displacement is treated as a longword offset, meaning that it is shifted left two bits (to address a longword boundary), sign-extended to 64-bitε and added to the updated contents of PC 33 to form the target virtual address (overflow iε ignored). Operate instructions have two different formats 72 and 73. The format 72 has three register operands, and the format 73 has two register operands and a literal. The operate format is uεed for inεtructionε that perform integer regiεter operations, allowing two source operands and one destination operand in register file 43. One of the source operands can be a literal constant. Bit-12 defines whether the operate instruction is for a two source register operation or one source register and a literal. In addition to the 6-bit opcode at bits <31:26>, the operate format has a 7-bit function field at bits <11:5> to allow a wider range of choices for arithmetic and logical operation. The source register Ra is specified in either case at bits <25:21>, and the destination register Re at <4:0>. If bit-12 is a zero, the source register Rb is defined at bits <20:16>, while if bit-12 is a one then an 8-bit zero-extended literal constant is formed by bits <20:13> of the instruction. This literal is interpreted as a positive integer in the range 0-255, and iε zero-extended to 64-bitε. Figure 8 also illustrates the floating point operate instruction format 74, used for instructions that perform floating point register to floating point register operations. The floating point operate instructionε contain a 6-bit opcode at bitε <31:26> aε before, along with an 11-bit function field at bits <15:5>. There are three operand fields, Fa, Fb and Fc, each specifying either an integer or a floating-point operand as defined by the instruction; only the registers 13 are specified by Fa, Fb and Fc, but these registers can contain either integer or floating-point values. Literals are not supported. Floating point conversions use a εubset of the floating point operate format 74 and perform register-to-register conversion operations; the Fb operand specifies the source and the Fa operand should be reg-31 (all zeros). The laεt instruction format 75 is used for privileged architecture library (PAL or PALcode) instructions, which specify extended procesεor functionε. In these instructionε a 6-bit opcode iε preεent at bits <31:26> as before, and a 26-bit PALcode function field <25:0> specifies the operation. The source and destination operands for PALcode instructions are supplied in fixed regiεters that are specified in the individual instruction definitions. The six-bit opcode field <31:26> in the instruction formats of Figure 7 allows only 2 or εixty-four different instructions to be coded. Thus the instruction set would be limited to sixty-four. However, the "function" fieldε in the instruction formats 72, 73 and 74 allow variations of instructions having the same opcode in bits <31:26>. The preferred embodiment of the present invention more particularly concerns a translator for translating programs for the CISC computer 20 of FIG. 1 to programs for the RISC computer 50 of FIG. 6. A major difficulty that must be addresεed by the translator is that it iε not always possible to translate all of the instructionε in the original CISC program. One reason that translation is not always possible is that the CISC architecture permits CISC programs to be executed from "read-write" memory areas so that the programs may modify themselves during execution. The RISC architecture, however, requireε programε to be executed from "read only" memory areas. Although CISC program, instructions to be executed from "read-write" memory areas cannot be translated to CISC instructions, they can be interpreted on .the RISC computer during execution time, at the expense of a severe penalty in execution speed. Fortunately, very few CISC programs modify themselves during execution. Many CISC programs that have program instructions in "read-write" memory areas, for example, do not actually modify themselves. A more typical reason for failing to translate all of a CISC program is the difficulty of finding all of the CISC inεtructions to be translated. To run a CISC program, only the starting address of the program need be known. Although one may parse the instructions beginning at the starting address, the CISC program usually will include at least one execution transfer instruction, such as a "Jump" or "Call" instruction, having a computed destination addresε. Although the destination address is easily computed at execution time, it could be entirely indeterminate at translate time, for example, because the destination address is computed based on program input data. In the typical case, however, the present invention provides techniques for resolving, at translate time, a majority of the computed destination addreεseε. Turning now to FIG. 8, there is εhown a block diagram of a CISC-to-RISC translator 80 and itε aεsociated input and output images and data structures. The translator 80 receives an original program 81 having CISC instructions and generates a corresponding translated program 82 having RISC instructionε. In association with the translated program 82, the translator 80 generates address conversion information 96, which correlates addresses of CISC instructions in the original program with addresses of RISC instructionε in the translated program. In addition to a RISC code generator 83, the tranεlator 80 includes a program analyzer 84 that analyzes the original program 81 to separate instructions from data, to trace program flow for RISC code optimization, and to detect CISC instructions that specify behavior that cannot be reproduced by the RISC instruction architecture. The program analyzer 84 may reference supplemental input 85 to find the location of instructions in the original program. The supplemental input 85 may include, for example, a linker map file 86 generated when the original program 81 was created by linking together a number of component images. In this case the linker map will identify entry points to instructions in the original program, and provide names for the entry points. These names are useful for making meεsages and other output of the translator more readable. The supplemental input 85 may include a program counter (PC) sampling histogram file 87 that might have been generated to identify frequently executed instructions in the original program. If a PC sampling histogram file is available, then the program analyzer may use it to ensure that an attempt is made to translate CISC instructionε at every program counter addresε having a sampling frequency greater than zero; i.e., every program counter address corresponding to an instruction that was executed at the time that the PC sampling histogram file waε generated. The supplemental input 85 may also include an execution log file 88 containing the addresses in the original program of instructions that were not translated in a previous translation, but which were interpreted by the interpreter during execution of the previously translated program. As further described below in connection with FIGs. 9 and 11, the execution log file is generated, for example, during interpretation of the previously untranslated code, and it includes pairs of the origin addresεeε in the original program of instructions which transfer execution to the untranslated code, and the destination addresseε in the original program where the untranslated code is located. The translator uεeε the information identifying the pairε of origin and destination addreεseε to translate the previously untranslated instructions in the original program. The origin addresseε are used to identify the execution paths that were not discovered during prior tranεlation of the original program. Aε further described below, identification of these execution paths SUBSTITUTE SHEET may permit the program analyzer 84 to discover additional execution paths that were not taken during execution of the previously translated program or interpretation of the untranslated portions of the original program. Preferably this feedback of information from execution to re-translation is performed after each execution of the translated program so that virtually all of the instructions in the original program will eventually be located and translated. The program analyzer 84 also generates auditing output 89 including error, warning and information messages 90; a summary page 91 showing a memory map of the original program 81 identifying regionε of the instructions that were found and the location of entry points; flowgraph language files 92 that define a flowchart of the translated portions of the original program 81; and an output image information file 93 for the original program. An image information file contains information about the interface characteristics or properties of predefined entry points in an image. The translator 80 generates an output image information file 89 for the original program 81 when the original program is firεt translated. During retranslations, the information input file for the original program can be used as an input file 94, and it will be updated during retranslation based upon additional instructions and execution transfer paths discovered by the program analyzer 84. Image information files are used by the program analyzer 84 to resolve references to other images and to generate the appropriate linkage. For example, when the original program 81 calls library routines, the supplemental input 85 should include image information files 95 for these shared library routines. Preferably the image information file is an ASCII file that is easily edited by the programmer to add or correct information. Turning now to FIG. 9, there is shown a block diagram of the images and data files uεed when executing the tranεlated program 82 on the RISC computer 50. In addition to the translated program 82 and its associated address conversion information 96, the RISC computer 50 uses as input a copy of the original program 81, an interpreter 101 that is written in RISC code for interpreting CISC instructions, and data input 102 for the original and translated programs. The interpreter 101 is called upon to interpret untranεlated instructions in the original program 81, so that the original program 81 serves as data input for the interpreter. The address conversion information 96 also serves as data input to the interpreter 101, and the interpreter useε thiε information when passing execution back to the translated program at appropriate times. The data output from the RISC computer includes output data 103 from the original and translated programε, and the execution log file 88, which is output data from the interpreter. Turning now to FIG. 10, there is shown a flowchart of steps in the RISC code generator 83 that generate calls to the interpreter when CISC instructionε are not translated prior to execution time. As noted above, code in "read-write" memory areas usually should not be translated because the program might modify the code during execution. The user may, however, believe that program will not modify the code during execution, and therefore the user may wiεh to have code in read-write memory translated to avoid the severe performance penalty associated with code interpretation. Therefore the user may set a software override switch, and in step 111 the RISC code generator 83 tests the override switch to decide whether to translate a CISC instruction in a "read-write" memory area. If the override switch is not set, then in step 112 the RISC code generator 83 checkε whether the CISC inεtruction iε in a read-write memory area. In thiε caεe, the code generator issues a message in step 113 to warn the user that the CISC instruction muεt be interpreted, and therefore a performance penalty will result. Then in step 114 the code generator generates RISC code to call the interpreter and pasε the CISC inεtruction addreεε aε a parameter. Finally, in step 115 the code generator advances to the next CISC instruction that is found in a "read-only" memory area, in order avoid tranεlating CISC inεtructionε that will be interpreted during the call to the interpreter. The RISC code generator cannot generate code for CISC instructions that cannot be located in the original program. The RISC code generator, however, can recognize execution transfer instructions in the original program that have unresolved computed destination addresses, and therefore generate RISC code that calls the interpreter to interpret the untranslated CISC instructionε at execution time. In εtep 116 the RISC code generator checkε whether the CISC inεtruction haε an unreεolved computed destination addresε. If εo, then, in εtep 117 the uεer iε warned that the interpreter muεt be called to interpret untranεlated CISC inεtructionε, and in εtep 118 the code generator generates RISC code to compute the destination address, and to call the interpreter and pass the addresε of the CISC execution tranεfer instruction and the computed destination address as parameters. In step 119, the code generator generates RISC code for a CISC instruction which does not have an unresolved computed deεtination addreεε. This is done by tranεlating the CISC instruction to one or more RISC instructions that have the same effect as the CISC instruction. This code translation iε made more efficient by using information from the program analyzer (84 in FIG. 8) about execution transferε and regiεter usage in the program. The RISC computer (50 in FIG. 6), for example, preferably has subroutine call and return instructions which reference a return address in a specified general purpose register, and the RISC computer provides a large number of general purpose registers. Therefore it is inefficient to translate CISC subroutine call and return instructions into RISC instructions which emulate stack operations in caseε where regiεter could be uεed instead. There is also an anomalous case of CISC instructions which reference the program counter directly as a source operand. In the preferred construction of the RISC computer, the program counter cannot be referenced directly as a source operand, although the program counter value can be computed by decrementing the return address provided by a subroutine call instruction. However, the program counter value in this case will be the program counter of the RISC computer, which is referenced to the RISC code, and not the program counter of the CISC computer, which is referenced to the CISC code. An excesεive amount of overhead would be required to maintain in a general purpoεe regiεter a conεtantly changing value corresponding to the CISC program counter. Therefore the program analyzer (84 in FIG. 8) will attempt to resolve references to the program counter for execution transfers in terms of relative jumps in the program, but will not attempt to translate code that uses the value of the program counter for any other purpose. Turning now to FIG. 11, there is shown a flowchart of the interpreter and itε interaction with execution of the tranεlated program, in εtep 131, inεtructionε in the tranεlated program 82 (or operating system routines called by the translated program) are executed until the interpreter is called. As shown, the interpreter is entered at a first entry point 132 when called to interpret a CISC instruction at a computed destination addresε, and iε entered at a second entry point 133 when called to interpret a CISC instruction in a "read-write" area of memory. A computed destination address might not necessarily be in an untranslated portion of the original program. Therefore, in step 134, the computed address iε checked to determine whether execution εhould continue in the interpreter, or whether execution should return to an entry point in the translated program or somewhere else. When the computed destination address is in the original program but does not correspond to an entry point in the tranεlated program, it is desirable to log the deεtination addreεε in the execution log file (88 in FIG. 8) together with the addreεε of the execution transfer instruction having the destination addresε. Thiε iε done in step 135. During retranslation, the program analyzer (84 in FIG. 8) readε the information in the execution log file to locate untranslated code, for the case where the computed destination address does not correspond to a translated CISC instruction, or to identify a new execution transfer path in the tranεlated program, for the caεe where the computed deεtination address correspondε to a tranεlated CISC instruction but not an entry point in the translated program. In step 136, the interpreter interprets the CISC instruction at the address in the original program. A general purpose register in the RISC computer is allocated to reproduce the contents of a corresponding register in the CISC computer. This set of allocated registers defines a model of the state of the CISC computer. The interpreter program reads the opcode of the CISC instruction and performs a table look-up to determine the number of specifiers to decode and the addresε of a program routine for the opcode. Then the interpreter decodeε each specifier. Literal and register source operands are transferred to general purpose registerε allocated aε source operand registers. Complex εpecifierε are decoded and the εpecified operands are fetched from memory and transferred to the general purpose registers allocated as source operand registers. Then the program routine for the opcode is executed. Finally, the destination specifier is decoded, and the result is transferred to the specified destination. In step 137 the address of the next CISC instruction in the original program is computed. This computation is based upon the instruction interpreted in step 136. The next CISC inεtruction follows the prior CISC inεtruction unless the prior instruction tranεferε execution, in which case the addresε of the next CISC inεtruction iε the deεtination addreεs of the prior instruction. In step 138 the computed addresε is checked to determine whether execution should continue in the interpreter, or whether execution should return to an entry point in the translated program or somewhere else. Execution in the interpreter continues in εtep 136. In addition, step 136 is the initial step from the entry point 133. SUBSTITUTE SHEET Turning now to FIG. 12, there is shown a flowchart of the address check routine used in steps 134 and 138 of FIG. 11. In step 141 the computed address is compared to the beginning and ending addresεeε of the original program to determine whether it iε in the original program. If the deεtination addreεs is outside of the original program, then the computed destination addresε, for example, could be the entry point of an operating system routine for the operating syεtem of the CISC computer (20 in FIG. 1). The operating εyεtem of the RISC computer (50 in FIG. 6) may or may not have a correεponding routine. Therefore in εtep 142, the computed deεtination addreεε iε validated, for example, by look-up in a table of CISC deεtination addreεεes having corresponding entry points in the RISC operating system. If the computed destination address is invalid, the error is reported and execution is terminated in step 143. Otherwise, in step 144, execution is transferred to the entry point of the RISC operating system routine corresponding to the computed destination address. When step 141 determines that the computed deεtination address is in the original program, it iε poεsible that the computed destination may correspond to a translated CISC instruction in the original program. But even in this case, it may be desirable to interpret the CISC inεtruction because it may be desirable for translation to assume that the CISC program has only certain predefined entry points so that the translator can translate blocks of CISC instructions rather than individual instructionε in order to generate more optimum RISC code. In any caεe, the interpreter must know the correspondence between CISC instruction addresses and correεponding entry points in the translated program if execution is ever to return from the interpreter to the translated program. This correspondence is provided by the addresε conversion information (96 in FIG. 8) associated with the translated program. Preferably this address conversion information is provided by a converεion table of the CISC addresses and corresponding entry points in the translated program. Therefore, in step 145, the interpreter checks whether the computed deεtination addreεε correεpondε to an entry point in the tranεlated program, for example, by look-up in the converεion table. When the computed deεtination addreεε corresponds to an entry point in the translated program, the interpreter uses the address conversion information to covert the computed CISC address to the RISC entry point addresε in step 146, for example, by reading the corresponding RISC entry point addresε from the conversion table. In step 147, execution returns to the entry point in the tranεlated program. Otherwiεe, in εtep 148, execution returnε to the interpreter. Turning now to FIG. 13, there iε εhown a flowchart of the steps performed by the translator 80. In the first step 161, the original program and the supplemental input files are read into memory. Then in step 162 the translator searches for entry points in the original program. This iε further deεcribed below with reference to a specific example for the original program organization shown in FIG. 14. In step 163 the translator follows threads of execution from the entry points in order to locate instructions in the original program and to generate a flowgraph of the program. The flow graph identifies "basic blocks" of instructions and execution pathε interconnecting the basic blocks. Each baεic block iε a sequence of contiguous instructions that has a single known entry point at the beginning of the basic block. Execution is transferred only to the beginningε of the basic blocks, and execution is transferred only from the ends of the basic blocks. The generation of the flowgraph is further described below with reference to FIGS. 18 and 19. In step 164 the translator scans the original program for plausible code. The result of εuch a scan is uεeful for quantifying the number of plauεible instructions in the original program for comparison to the number of instructions located by the translator. The result of the comparison, for example, is an eεtimate of the "percentage of code found" computed aε 100 timeε the byteε of known code divided by the sum of the bytes of known code and the bytes of plausible code. This estimate can be used by a εyεtems analyεt in choosing a porting strategy for the original program or for monitoring or augmenting the performance of the tranεlator. If the tranεlator is unable to translate a high percentage of the instructions, then the systems analyst may run a number of teεt caεeε upon the tranεlated program and employ feedback of information from execution to re-translation to reduce the indicated estimate of untranslated code before releasing the translated program for general use. As a laεt reεort, the εyεtemε analyεt may have to search for documentation by the original programmer or inεpect the code at the addreεs locations indicated as containing plausible instructionε in an attempt to verify the eεtimate and make a judgement whether to releaεe the tranεlated program for general uεe, or to direct the tranεlator to translate the plausible code that is believed to contain untranslated instructionε. The preferred method of εcanning for plauεible code iε described further below with reference to FIGS. 29 and 29. In step 165 the flowgraph is analyzed to find possible errors indicated by deviations from typical programming practices and standard conventions. In a typical program, for example, a data item is pushed on a stack so that it can be popped off at a later time, without regard to how many other data items are pushed on and popped off the stack by intervening instructions. If the number of pushes do not cancel the number of pops in the intervening instructions, then errors will be caused by improper programming of the intervening push and pop instructions. If the intervening instructionε include separate paths that branch apart and rejoin at an intervening node, and the improper programming occurε in one of the pathε, then the improper programming will alεo cauεe the calculated εtack depth to be different for the two pathε when they join at an intermediate node. This is especially likely to cauεe an error if the node iε an RSB .subroutine return instruction. Therefore, one of the error checks performed with the aid of the flowgraph is to calculate the stack depth at all pathε from the main entry pointε of the original program, and to check whether the calculated εtack depth iε the same whenever these paths rejoin. If not, the translator issueε a warning message that says: "Stack depths don't match on all incoming paths at VA=%X", where VA is the virtual addreεs of the node in the original program. The flowgraph is also analyzed for compliance with typical programming conventions of the CISC inεtruction architecture. For the VAX™ architecture, for example, a "return mask" is used in connection with procedure calls (CALLS and CALLG instructions) to indicate which registerε to load during a return. If the return masks are different depending on the path to the return instruction, then there probably was a programming error. The translator issues a warning: "Return Masks don't match on all incoming paths VA=%X". in addition, if a RET instruction is found that may be executed with different return masks, that instruction must be translated as a call to the interpreter so that the interpreter will inspect the return mask to determine the particular registers to load during the return. Another calling convention associated with the procedure callε iε that register and condition code bitε are to be set by the procedure before they are used in the procedure, rather than using register values or condition codes that might be set by the calling routine. If a deviation from this calling convention is found, the translator issues the warning: "Possible uninitialized variable(s) at call entry VA=%X: %s". The "%ε" in thiε message standε for a liεt of the possible uninitialized variables that were found. Other deviations from coding conventions of the VAX " instruction architecture include a failure to align the stack on longword boundaries (which causes a severe performance penalty for the RISC code), the use of a RET instruction to return from a JSB, and the uεe of an RSB instruction to return from a CALLS or CALLG. The translator analyseε the flowgraph for theεe deviationε and iεεueε warning messages identifying the particular deviation and a corresponding addresε. To reduce the amount of required εearching through the flowgraph, the analyεiε of the flowgraph for poεεible errors also performs propagation of reεources used in each basic block. Each basic block uses various resources, such as the stack, general purpose registerε, and condition codeε. To deduce the behavior of subroutineε, their resource usage is propagated back to their calling routines. This information is used to terminate the search for the setting of a register used in a subroutine called by a CALLS or CALLG instruction, and this information is also used later during RISC machine code generation (step 168) to avoid needless generating of condition code or register values that are never used. Moreover, the consistency checks can be performed by comparing the resources for the basic blocks. For example, the "return mask" warning is generated when a basic block has two or more preceding basic blocks and the return masks for the preceding basic blocks are different, and the "stack depth" warning is isεued when a baεic block has two or more preceding basic blocks whose stack depth changes are different. A final scan over all of the basic blockε iε used to uncover any failure to align the stack on longword boundaries (i.e., a stack change for a basic block that is not divisible by four bytes), the use of a RET instruction to return from a JSB, and the uεe of an RSB instruction to return from a CALLS or CALLG. In step 166 the image information file for the original program is created, using the information about the resources used in each baεic block. The image information file, for example, consistε of an image header, which identifieε the image name and verεion of the image being deεcribed, followed by a series of image property records (one per line) each of which attaches a particular property to an offset in that image. Each property record consists of an image offset followed by the property name, optionally followed by a comma- delimited list of attribute values. The attribute values are specific to particular properties. An image offset is a representation of the offset in the image to which the property applies. It may consist of a symbol (which could be defined by other image information file records) +/- the hexadecimal offset value. Either the symbolic name or the offset value may be omitted (but not both). The properties and their defined attributes preferably include: Interface Properties Property Name Attributes Interpretation absolute ok specifieε RISC operating εyεtem εupport for entry point jmpentry symbolic name defineε a JMP entry point and name callback parameter number defineε a CALL to a procedure parameter calientry symbolic name defineε a CALL entry point and name caselimit integer εpecifies maximum number of caseε delta sp integer specifies change in stack pointer by routine image identification identifies the image that the image information file describes jmpback parameter number defineε a JMP to a procedure parameter jεbentry symbolic name defineε a JSB entry point and name no standard return specifieε no εtandard return setε list of registers εpecifies registerε set by routine εymbol symbolic name attaches a symbolic name to an offset uses list of regiεters specifieε regiεterε uεed by routine An informal representation of the syntax of an image information file iε shown below. <WHITESPACE> non-null sequence of tabε and spaceε <COMMA> [<WHITESPACE>] ',' [<WHITESPACE>] <NL> newline <comment line> ' ; ' any text <NL> <IIF file> <IMAGE_ID> <IMAGE_PROPERTIES> <IMAGE_ID> <WHITESPACE> 'image' <IMAGE_NAME> <COMMA> <VERSION> <NL> <IMAGE_PROPERTIES> :— <IMAGE_OFFSET> <PROPERTY> [<ATTRIBUTE>, ... ] <NL> <IMAGE OFFSET> :«= [<SYMBOL>] ( '+'|'-') [<OFFSET>] <IMAGE_OFFSET> :== [<SYMBOL>] C+'l'-') [<OFFSET>] Comment records (lines beginning with ';') may occur anywhere in the file and are ignored by the translator, An example of an image information file is shown below, for an image named "VAXCRTL": ; comments image VAXCRTL, "VO5-001" +000000 jsbentry "C$MAIN" +000000 uses "AP FP SP RSB " +000000 sets "RO Rl R2 R3 R4 R5 R6 R7 R8 R9 R10 AP SP N Z V C" This image information file provides the tranεlator with the following information about VAXCRTL. VAXCRTL+0 (i.e., the first memory location in the image, at an offset of zero from the beginning of the image) is marked as a JSB entry with the name C$MAIN. From this information, the tranεlator can confirm that the JSB is proper, and can insert the name VAXCRTL:C$MAIN TM into flowgraphs. VAXCRTL+0 is also marked as using VAX registers AP, FP, and SP, and the VAX instruction RSB. From this last piece of information, the translator can legitimately continue parsing VAX instructionε at the return point, juεt after a calling instruction in a calling image. VAXCRTL+0 is also marked as setting VAX™ registerε RO RIO, AP, and SP, and the VAX condition code bits NZVC. From this information, the translator can infer, for example, that a test of RO after the calling inεtruction refers to the value left in RO by C$MAIN, not to an earlier value put in RO by the calling image itself. The following example shows an image information file for a library file, LIBRTL, that has numerous entry pointε: ; comments image LIBRTL, V05-000 +000000 jsbentry LIB$AB_ASC_EBC +000000 jsbentry LIB$AB_EBC_ASC +000200 jsbentry LIB$AB_UPCASE +000300 callentry LIB$ANALYZE_SDES +0004F0 callentry LIB$SIGNAL +0004F8 callentry LIB$STOP LlB$STOP no_standard_return +000500 callentry LIB$SIG_TO_RET +000508 callentry LIB$SKPC In step 167 of FIG. 13, a flowgraph language file is created for the translated program. This flowgraph language file can then be used aε input to flowgraph program that will send commands to a laser printer to draw a flowgraph of the translated program. The flowgraph program, for example, may also receive an optional scale parameter that controls the size of the printed flowgraph, and an optional "code block" parameter that may specify the addreεε of a particular block of code to be printed on a page with other blocks to which it is connected. The flowgraph consists of different kinds or shapes of blocks, arcs interconnecting the blocks, and instructions printed in asεembler notation in each block. Each baεic block of inεtructions found by the translator has a correεponding block in the flowchart. The flowgraph language file containε a definition of the kinds of blocks in the flowgraph, the interconnections between the blocks, and the instructionε (in ASCII, assembler notation) that go into each block. The flowgraph language file is created from an internal binary data structure that includes a data block or record defining each basic block of instructionε found by the translator. Each data block or record contains the starting addresε (in the original program) of the basic block of instructionε, the length of the basic block in byteε, the kind of the block, an "epoch number" attribute used to indicate whether the block has been included in a particular search, a list of addresεeε of "successor" data blocks, and a list of addresεeε of "predeceεεor" data blockε. A data block can be created dynamically and eaεily inserted or removed from the data structure by inserting or deleting references to the data block in its successor and predecessor blocks, and the data structure iε easily searched or scanned in either a forward or backward manner by εucceεsive references to the succesεors or predecessors. There are five possible kinds of blocks used in the flowgraph, and each kind of block has a distinctive shape. The kinds of blockε include CALLx entries, JSB entries, "normal" blockε, CALLx placeholders, and JSB placeholders. "CALLx" refers to a procedure call, which iε made by a CALLS or CALLG instruction in the VAX™ instruction architecture. In the printed flowgraph, a CALLx entry block is hexagonal and contains the name of the block, the name of the procedure if known, and the call mask in hex. The name of the block consiεtε of the addreεε (in the original program) of the fist byte of the block in hex followed by "_CALL". A CALLx entry block is reached via a CALLS or CALLG instruction. In the VAX™ instruction architecture, the main entry point of the original program is a CALLx entry block; this main entry point is called by the operating syεtem to run the program. In the printed flowgraph, the JSB entry block is oval and contains the name of block, and the name of the subroutine if known. The name of the block consists of the address (in the original program) of the firεt byte of the block in hex followed by "_JSB". A JSB entry point is reached via a JSB, BSBB, or BSBW instruction. JSB entrieε are typically used in macro code. In the printed flowgraph, a normal block is rectangular and contains the name of the block and all of the instructions within the block. The name of block is the address (in the original program) of the first byte of the block in hex. A normal block is reached via the normal flow of execution or via an execution transfer from a branch, case, jump, or return instruction. In the printed flowgraph, a CALLx placeholder block is dashed hexagonal and contains the name of the block, and the name of the called procedure if known. The name of the block consists of the address (in the original program) of the first byte of the called procedure in hex (if known at translate time, or elεe zero), followed by "_" and a "call number" of the placeholder for the called procedure. A Callx placeholder block repreεentε the flow in and out of a procedure and any recorded εide effectε for each call of that procedure. If a procedure iε called from five different places, there will be five different placeholder blocks with five different call numbers for those callε (in addition to a CALLx entry block for the procedure). In the printed flowgraph, a JSB placeholder block is dashed oval and contains the name of the block, and the name of the εubroutine if known. The name of the block consistε of the addreεε (in the original program) of the first byte of the subroutine in hex (if known at translate time, or else zero), followed by "_" and a unique "call number" of the placeholder for the called subroutine. A JSB placeholder block representε the flow in and out of a subroutine and any recorded side effects for each call of that subroutine. In a preferred form of the flowgraph language, there are three basic operators: graph (G), block (B) and arc (A) . Each line of the flowgraph language file starts with one of these operators; a semicolon, indicating that the line contains a comment; a blank, indicating that alphanumeric data in the line to be included in a block defined by a previous line having a block operator; an H followed by a block name, indicating that a named block is to be highlighted; or a C followed by the names of two blocks, indicating that the two blocks are to be connected with a wide dotted line, for example to highlight a path including an error. A line beginning with the operator G delimits a new graph, and may include alphanumeric text that is printed aε a heading for the graph. A line beginning with the operator B also includes a name (such as a hex address) for a block of code. D=CALLx placeholder, E=JSB placeholder). An optional numeric εcale factor may immediately follow the operator B. A line beginning with the operator A εpecifieε a directed arc from a firεt-named block to a εecond-named block, and after the two block nameε, a letter code indicateε the εtyle of the arc (e.g., A=normal branch drawn with a solid line, B=true branch drawn with a dotted line). The following is an example of a flowgraph language file for printing the flowgraph in FIG. 15: ~ f FLOWGRAPH LANGUAGE FILE FOR DHRYSTONE_SHR G DHRYSTONE_SHR B 2E00_CALL B 2E00_CALL main Transfer_address mask:0000 A 2E00_CALL 2E02 A B 2E02 A 2E02 SUB2 #08, SP JSB @0000063D(PC) A 2E02 0_12972C_1 A B 0_12972C_1 E 0_12972C_1 VAXCRTL:C$MAIN A 0_12972C_1 2E0B A B 2E0B A 2E0B CALLS #00, 00000006(PC) A 2E0B 2E18_1297E4_1 A B 2E18_1297E4_1 D 2E18_1297E4_1 ProcO A 2E18_1297E4_1 2E12 A B 2E12 A 2E12 CVTWL #0001, RO RET In step 168 of FIG. 13, the translator receives the basic blocks of instructionε from the original program, and generates corresponding RISC machine code. The CISC instructionε are tranεlated one at a time into RISC instructions that will reproduce the same reεultε and condition codes. Preferably each CISC instruction iε translated into a corresponding sequence of RISC instructions including in sequence four groups of inεtructionε. The firεt group haε instructionε that fetch source operands and place them in temporary storage. The instructions in the second group operate upon the source operands to produce results in temporary storage. The instructions in the third group update the contents of memory or registerε and are εubject to possible exceptions. Finally, the instructions in the fourth group are those that update the contents of memory or registerε and are free of poεεible exceptionε. For further details regarding the translation of the CISC instructions to RISC instructions, one may refer to the above-cited related application by Scott Robinson and Richard Sites entitled "Improved Syεtem and Method of Preserving Instruction Granularity for Translated Program Code." In step 169 of FIG. 13, the translator creates the translated program by placing the RISC machine code into a program image format that is recognized by the operating system of the RISC computer. In asεociation with this translated program image, the translator also generates a mapping between the address of each basic block of CISC instructions in the original program and the addresε of the corresponding basic block of RISC instructions in the translated program. In step 170 of FIG. 13, the translator creates a summary page, which graphically illuεtrateε where the translated code is located in the program image. The summary page is further described below with reference to FIG. 14. Finally, in step 171 of FIG. 13, the translator may create flowgraph language files for printing flowgraphs of subroutines having errors that were located in step 165 during analysiε of the program flowgraph. An example of an error-εpecific flowgraph iε εhown in FIG. 16. The SUBSTITUTE SHEET error-specific flowgraph has enlarged blocks 210, 211, 212, and 213 along the path where the error was traced, and a heavy dotted line 214 along an arc over the path where the error was traced. The error indicated in FIG. 16 iε an uninitialized variable (general purpoεe register R3) being used in a procedure. The heavy dotted line 214 connects the block 210 at the beginning of the procedure to the block 213 where the uninstantiated variable waε firεt used. This error was not diεcovered prior to being revealed by the tranεlator becauεe during execution of the original program, execution apparently never followed the indicated error path around block 215. Turning now to FIG. 14, there is shown a summary page of the kind generated in step 170 of FIG. 13. Aε εhown in FIG 14, the εummary page includeε a memory map 181 of the original program. At the top of the memory map, there is an annotation including the program name 182, the date 183 when the original program was created, and the percentage 184 of code found during the translation. The memory map 181 shows the organization of a typical program using the VAX instruction architecture and VMS™ operating syεtem. The program includes a header 185, a read/write image section 186, a number of read-only sections 187, a fixup vector section 188, a debug symbol table (DST) 189, a debug module table (DMT) 190, and a global symbol table (GST) 191. The number 192 of disc blocks per line of the memory map is printed at the upper left of the memory map, and the total number 193 of disc blocks in the memory map is printed .at the lower right of the memory map. In this example, there is one disk block per line, and 12 disc blocks total. The translated code is indicated by narrow bands 194, 195 and 196 in the read-only section 187. These narrow bands are made up of a short vertical line for each byte of code that is translated. Plausible code is indicated by a wider band 197. To the right of the memory map 181, the summary page lists up to 100 entry points that are defined by the image format of the original program. During step 161 of FIG. 13, the translator parses the command line of switches and the file name at the beginning of the original program, and reads the original program into memory. The in step 162 of FIG. 13, the translator searches for the entry points defined by the image format of the original program. The translator looks at the first few and last few bytes of the first diεc block to see if it is a header for a translatable VAX /VMS program image. If so, the translator parseε the rest of the header, looking for image section descriptors (ISDs), t 67 and organizing the disk blocks into the described image sections, such as the images sectionε 185-191 εhown in the memory map 181 of FIG. 14. If a VAX™/VMS™ fixup vector iε present, the translator parεeε it to determine addreεses in the original program that are indirect references to other images. To find entry points that are defined by the image format of the original program, the translator εcanε the image header 185 for entry pointε but ignoreε debugger entry points. The translator then scans, when present, the debug symbol table (DST) 189 and, when present, the global symbol table (GST) 191, to find CALL entries and SYMBOL entries. Validity checks are performed on each possible CALL entry point, such as insuring that the CALL mask is valid, the mask iε followed by legal code, and the code doeε not contain privileged instructions. The legal code check decoded the code through three layers of baεic blocks from the call mask. SYMBOL entries are ignored when the symbolε are flagged by the linker aε being absolute referenceε, because absolute references are typically constants. Otherwise, a SYMBOL entry might be a JSB entry point or a mislabeled CALL entry point. The code from the entry point is decoded and the legal code check just described is performed assuming that the entry point is a CALL entry, and if this legal code check is passed, the entry point is deemed to be a CALL entry. If the legal code check is not pasεed, then a εimilar legal code check iε performed to teεt whether the entry point is a JSB entry. The summary page of FIG. 14 listε up to 100 of the entry points 198 that are defined by the image format of the original program. To show the locations of the entry points in the program code, an arc 201 is drawn from each of the entry points 194 to a corresponding position in the memory map 181. Below the list of entry points, the summary page includes a summary 199 of messages from the translator, listed in decreasing order of severity, from fatal to informational. The number of times each message is given is shown in parentheseε. Finally, in the upper right-hand corner of the εummary page, the tranεlator gives a letter grade of the translation, ranging from A to F, indicating quality ranging from full translation, translation with warningε, partial tranεlation, partial translation with possibly severe errors, partial translation with misεing runtime facilitieε, to no successful translation at all. To locate most of the instructions in the original program, it is necessary to follow threads of execution from the entry points that are defined by the image format of the original program. The threads of execution are followed by decoding the sequence of instructionε beginning at each entry point and building a flowgraph as the instructions are decoded. To build the flowgraph, each instruction is decoded to determine its length, and to determine the next instruction or instructions in the sequence. The length of the inεtruction iε determined by referencing a table giving the number of specifiers for each opcode, and then inspecting the specifierε to determine their lengths. Becauεe the CISC inεtructionε muεt alεo be decoded for generating the RISC code, the translator may save the results of the decoding for building the flowgraph. These resultε could be in an intermediate code format that simplifies the analysis of the instructions during error checking with the aid of the flowgraph, and alεo simplifies the generation of the RISC code. The intermediate code format may provide fixed.data formats for similar instructions so that the operand specifiers are in readily accessible memory locations. The fixed data formats may also provide attributes that aid, in the generation of efficient RISC code and, when neceεεary, calls to the interpreter. One kind of intermediate code format that could be uεed is described below in Appendix A to the present specification. Memory space limitationε, however, may preclude the uεe of an intermediate code representation for long programs. Turning now to FIG. 17, there are shown the data structures used for building the flowgraph. The flowgraph data structure 221 was described above; it is a list of basic block descriptors, each of which is linked to all of its predecesεorε and succesεorε. To aεsist in the generation and analyεiε of the flowgraph, it is desirable to reference and maintain a number of auxiliary data εtructureε 223. During the building of the flowgraph data structure 221, and later during the scan for plausible code, for example, it iε deεirable to know quickly whether a given address iε (1) an addreεε of neither a decoded instruction nor the beginning of a block; or (2) the address at the beginning of a basic block (hereinafter referred to as a "block entry point"); or (3) the address of a decoded instruction that is in the middle of a block; or (4) the addresε of a byte in the middle of a decoded inεtruction. For this purpose the auxiliary data structures 223 include a table 224 indexed by CISC instruction address. An entry in the table 224, for example, is a longword packed with sixteen pairs of bits encoding the four mutually-exclusive states of each CISC address just mentioned. For a given CISC address in a first register, a second register is loaded with a mask having its four least significant bits set, the four least significant bits of the addresε are transferred into the second register by a logical AND of the first and εecond registerε, and the second register is left-shifted by one bit position to provide a shift count. The first register is right-shifted by four bit positionε to provide an index into the table 224, and the entry from the table iε loaded into the firεt regiεter. The firεt regiεter iε then rotated by the number of bit positions indicated by the shift count, to right-justify the pair of bits for the given CISC address. The pair of bits is then masked out by a logical AND of the second regiεter with a mask having its two least-εignificant bitε set. When building the flowgraph, it is necesεary to follow one path at a time, even when it iε known that there are other pathε that have not been followed to terminal inεtructionε. Moreover, εometimeε the path being followed will merge with a partially followed path. Therefore it iε desirable for the auxiliary data structures 223 to include a list 225 of pointerε to the basic block descriptors of undecoded blocks. At the start of building the flowgraph, for example, baεic block descriptors of undecoded blocks are created for each of the known entry points of the original program. These known entry pointε are collected in a list 226 prior to building the flowgraph. For VAX/VMS programs, the known program entry points are entry points for CALLx procedure calls, so they are represented in the flowgraph by CALLx basic block descriptors. A CALLx basic block descriptor is created for each program entry point. The liεt 225 iε initially loaded with pointers to the CALLx basic block descriptorε of the program entry pointε. Moreover, the entries in the table 224 for the program entry pointε are initially set to indicate the beginnings of the basic blocks. When a look-up in the table indicates that a given CISC addresε iε the εtart of a block or a decoded inεtruction in a block, it iε often deεirable to quickly find the basic block descriptor of the block. If there were no limit to memory space, this could be done by a table of pointers to the basic block descriptorε indexed by CISC addreεε. Due to memory εpace limitations, however, it is preferable to use a hash table 227 to short lists of pointers 228 to the baεic block deεcriptorε in the flowgraph data εtructure 221. Moreover, it iε desirable for the hash table to be indexed by, for example, the sixteen leaεt εignificant bits of the address of the first instruction in the block. To find the basic block descriptor for a baεic block εtarting at a given CISC addreεε, for example, the haεh table 227 iε indexed by the εixteen leaεt εignificant bitε of the given CISC addresε to obtain a pointer to one of the short listε 228 of pointerε to the basic block descriptors. For each pointer in thiε εhort liεt, the pointer iε used to fetch the starting addresε attribute of the basic block descriptor, and this starting address is compared to the given CISC addresε. When a match occurs between the addresses, the desired basic block deεcriptor is found. To find the basic block descriptor including any given address (such as the addreεε of an inεtruction in the middle of a baεic block), the table 224 iε εcanned in a direction of decreaεing numerical addreεε until the address of the beginning of the block is found, and then the address of the beginning of the block is used to find the basic block descriptor with reference to the hash table 227 and the short lists 228 of pointers to the basic block descriptors. Each time that a basic block descriptor is allocated for a newly-created basic block, the addresε table 224, the hash table 227, and one of the short lists 228 are updated. A two-bit entry indicating the start of the block is written into the table 224 by indexing the table, for example to obtain a longword, and εetting the two-bit entry in the longword by a maεking operation. Mask for the masking operation, for example, are obtained by indexing a table of masks with the least εignificant four bits of the CISC address of the start of the basic block. Then a pointer to one of the short listε of pointers 228 is obtained by indexing the hash table 227 with the sixteen leaεt εignificant bitε of the CISC addreεε of the start of the basic block. Finally, a pointer to the basic block descriptor of the new block is added to the εhort liεt indicated by the pointer obtained by indexing the haεh table 227. Turning now to FIG. 18, there is shown a flowchart of the procedure for building the flowgraph data structure. In the first step 229, the undecoded basic block at the head of the list (225 in FIG. 17) is removed from the list, a basic block descriptor in the flowgraph data structure (224 in FIG. 17) is allocated, and the basic block descriptor is set to indicate a block entry point equal to the unresolved entry point and predecesεorε equal to the predecessor or predecesεors of the unresolved entry point. Next, in step 230, the next instruction in the basic block, which begins at the block entry point, iε decoded, and the addreεs table (224 in FIG. 17) is updated. Then in step 231, during decoding of the instruction, the address table (224 in FIG. 17) is indexed to determine whether the instruction being decoded overlaps a previously decoded instruction. If so, then in step 232 an error message is generated, and the path is abandoned; another path is searched if the list (225 in FIG. 17) of undecoded baεic blockε iε not empty, as tested in step 238. In step 233 the look-up in the addresε table (224 in FIG. 17) also indicates whether the decoded instruction overlaps an undecoded basic block. If so, there is an error because the block entry point of the undecoded basic block would be in the middle of an instruction. In thiε case, the error is reported in step 234, and the undecoded basic block is removed from the list (225 in FIG. 17) of pointers to undecoded baεic blockε under the assumption that the unresolved block entry is erroneous. At this point one instruction has been added to the flowgraph. An execution transfer instruction will always cause the termination of a baεic block. This condition is checked in step 235. When an execution transfer instruction is found, the next instruction for each of the possible execution paths of the instruction is investigated in step 236. A path back to previously decoded instructions is linked up to the entry point of an existing block or, when the path is directed to the middle of an exiεting block, the existing block is split into two blocks so that the path will always end at a block entry point. Otherwise, the investigation may conclude that the path should be terminated or εhould be followed. If there iε more than one path to be followed, then the higheεt priority path iε εelected aε a "continued path" and the addreεεes at which the other paths should be followed are queued as undecoded basic blocks with the basic block descriptor for the execution transfer instruction added to the list of predecesεorε in the each of the basic block descriptors of the undecoded basic blocks. For a conditional branch instruction, for example, the execution path in address sequence (i.e., the straight-line path) is the high priority "continued path" and the destination addresε of the execution transfer or "true branch" is queued. The manner in which each possible execution path is investigated in step 236 is described further below in connection with FIG. 19. If none of the possible execution paths are to be continued, as checked in step 237, then in step 238 the list of undecoded basic blocks is checked to determine if there are any other paths to follow. If not, the flowgraph is finished. Otherwise, execution loops back to step 229 to start following the path from the block entry point of the next undecoded basic block in the list of undecoded basic blocks (225 in FIG., 17). If εtep 237 decides that there is a continued path, then in step 239 execution branches either to step 246 if the path continues in an undecoded basic block, or otherwise to step 240. (Step 263 in FIG. 19 aε deεcribed below will have already checked whether the path continues in a decoded basic block, so that step 240 is reached only when the path continues to an undecoded inεtruction.) In εtep 240 a new baεic block iε created for the next instruction, the list of predeceεεorε for the new baεic block iε set to initially include a pointer to the basic block containing the execution transfer instruction, and a pointer to the new basic block is added to the list of successorε in the baεic block descriptor of the basic block containing the execution transfer instruction. In step 246, a pointer to the basic block containing the execution transfer instruction is added to the liεt of predeceεsorε for the undecoded baεic block, a pointer to the undecoded baεic block iε added to the liεt of successors for the basic block containing the execution transfer instruction, the pointer to the undecoded basic block is removed from the list of undecoded baεic blockε, and decoding beginε in εtep 230 for the undecoded baεic block; if decoding of the next inεtruction iε εucceεεful, the basic block descriptor of the undecoded basic block is updated to indicate that it has been decoded. When step 235 finds that an instruction in a block is not an execution tranεfer instruction, then the path is followed to the next instruction in address sequence. It is posεible that thiε path may have to be terminated becauεe it goeε out of the predefined instruction memory area. Depending on the user's choice, the predefined instruction memory area may be defined as a read-only memory area, or in any case the predefined instruction memory area is limited to the memory area allocated for the entire original translated program. Therefore, in step 241, execution branches to step 242 where the error is reported, and the path is discontinued. Execution then continues in εtep 238 to look for a new path to follow. The basic block will also end when the next instruction in address sequence runs into another basic block, which is a succeεεor block. This condition is checked in step 243, by indexing the address table (224 in FIG. 17) with the addresε of the next instruction. In step 244 the basic block descriptor of the succesεor block is accessed to determine whether the succesεor block iε either a decoded basic block or an undecoded basic block. If it is an undecoded succesεor block, then in step 246 a pointer to the baεic block containing the last decoded instruction is added to the list of predecessors for the undecoded basic block, a pointer to the undecoded basic block is added to the liεt of εuccesεorε for the basic block containing the last decoded instruction, the pointer to the undecoded baεic block iε removed from the liεt of undecoded basic blocks, and decoding begins in step 230 for the undecoded baεic block; if decoding of the next inεtruction iε εucceεεful, the baεic block deεcriptor of the undecoded baεic block iε updated to indicate that it haε been decoded. Otherwiεe, if the εucceεsor block is a decoded block, then in step 246 a pointer to the successor block iε added to the liεt of εucceεεors in the basic block descriptor of the block containing the last decoded instruction, and a pointer to the block containing the last decoded instruction iε added to the liεt of predecessors in the basic block descriptor of the successor block. Execution then continues in step 238 in to look for a new path to follow. Turning now to FIG. 19, there is shown a flowchart of a procedure followed in εtep 236 of FIG. 18 for inveεtigating the next instruction in one of the paths from an execution transfer instruction, in the first step 251 of FIG. 19, the execution transfer inεtruction is inspected to determine whether it has a computed destination addresε. If it doeε, then in εtep 252 a proceεε of backward εymbolic execution is performed in an attempt to resolve the destination. This process is particularly useful for resolving procedure and subroutine calls. If the destination iε not resolved, as checked in εtep 253, the investigation of the path terminates, because the next instruction in the path is not known and will not be determined until the interpreter is called at execution time. In the process of backward symbolic execution, the computed destination address is resolved by a backward search from the execution tranεfer inεtruction through the flowgraph to find at least one prior instruction which is used to resolve the computed destination addreεs to an address value that is fixed with respect to the addresεeε of the instructions in the program. The process of backward symbolic execution is further described below in connection with FIG. 20. Continuing now in εtep 254, the path being inveεtigated will have a known deεtination address. This destination address is compared to the limits of the memory allocated to the original program, and if it is outside thoεe limits, the destination is considered to be an external reference, such as an operating system routine. In step 255 a search is made for an image information file containing information about the external reference. If such an image information file is available, then it is inspected in step 256 to determine the destination or destinations where the path will continue from the external reference. If the external reference is a procedure or subroutine, it iε desirable to create a "placeholder" block to hold information about behavior of the subroutine or procedure call. The subroutine or procedure may have abnormal behavior such as not returning, returning to 4(SP), or modifying the caller's regiεters. This abnormal behavior should be indicated in the image information file, and used if posεible to determine the return path or pathε from the external program, in addition, it is desirable to record in the image information file for the original program information about the call, such aε the external destination address, the call type, the number of parameters, and any definite values for the parameters. Definite values for the parameters, for example, might be found by backward symbolic execution from the call instruction. This information about the call could be used in a process of iterative translation of multiple programs, as described below with reference to FIGS. 31 to 33. If an image information file iε not found for an external reference, then in εtep 257 the opcode of the execution transfer instruction is inspected to decide whether the external reference is a subroutine or procedure. If the execution transfer instruction is not a subroutine or procedure call, then in step 258 a warning is issued indicating that no return was asεumed for the external reference, information about the call iε recorded in the image information file for the original program, and inveεtigation of the path iε terminated with the concluεion that the path cannot be followed. If the execution transfer instruction is a subroutine or procedure call, then in step 259 a warning is issued indicating that a standard return is assumed for the external reference, and information about the call is recorded in the image information file for the original program. It is alεo desirable to create a "placeholder" block at this point in the flowgraph to hold the information that is assumed about the effects of the subroutine call. Investigation of the path is continued assuming that the destination of the path is the next inεtruction in address sequence following the execution transfer instruction. At step 260, the destination of the path being inspected has been resolved to a deεtination within the memory area allocated to the original program. In step 260 the destination is compared to the limits of the memory area allocated to the instructionε in the original program. In the uεual caεe, the memory area allocated to the instructions in the original program iε a read-only memory area, such as the area 187 shown in the memory map 181 of FIG. 14. If the deεtination iε outεide of thiε memory area, then an error eεεage iε iεεued in εtep 261 and the path iε abandoned. At step 262, the destination could be in the previously decoded instructions, where it could be terminated. To check for this condition, the table (224 in FIG. 17) is indexed with the destination, and the table entry is inspected to εee whether the addresε is in the middle of a previously decoded instruction, or whether the addreεs is the address of a previously decoded inεtruction, or an inεtruction at the beginning of a baεic block; if not, the deεtination iε at the middle of an exiεting block. Theεe operationε perform the tests in steps 262, 263, and 264 of FIG. 19. If step 262 determines that the destination iε in the middle of an existing block, then in step 265 the existing block is split into two blocks by the creation of a new block having as predecesεors the exiεting block and the block containing the execution tranεfer SUBSTITUTE SHEET instruction. In addition, all of the successors of the existing block are transferred to new block, the basic block deεcriptor of the exiεting block iε alεo updated to indicate the εhorter block length, a pointer to the new block iε added to the liεt of εucceεεors in the basic block descriptor of the block containing the execution tranεfer inεtruction, and the table of instruction addresses is updated to reflect the change in the existing block. Next, in step 266, backward symbolic execution is re-iterated for any computed destination addresεes in the new block and in any block in the line of successors of the new block in order to attempt to resolve additional destinations by backward symbolic execution back through the path being investigated. This completes the investigation of the path. If step 263 determines that the destination is at the beginning of a decoded block, then in step 267 a pointer to the block including the execution transfer instruction is added to the list of predecessors in the basic block descriptor of the existing block, and a pointer to the existing block is added to the list of successors in the basic block descriptor of the block including the execution tranεfer instruction. Backward symbolic execution back through the path under investigation is re-iterated in step 266 for any computed destination addresεeε in the exiεting block and the line of εuccessorε from the existing block. This completeε investigation of the path. If step 264 determines that the destination is in the middle of an existing instruction, then an error mesεage iε issued in step 268, and the investigation of the path is finished. If step 264 does not determine that the destination is in the middle of an existing inεtruction, then in step 269 the opcode of the execution transfer instruction is inεpected to determine whether it iε a procedure or εubroutine call. If so, then in εtep 270 the path is followed into the procedure or εubroutine. If the subroutine is not already translated, it is translated. In any case, a "placeholder" block iε created in the flowgraph to εtore information about the effectε of the particular procedure or subroutine call. If the subroutine is not already translated, the procedure or subroutine iε analyzed to inεure that it doeε not modify the return addreεs or saved registerε on the εtack. The analysis may reveal the presence of "callbacks", as further described below with respect to stepε 372 and 373 in FIG. 24. If the εubroutine call found in εtep 269 occurε to an entry point for which a callback iε noted, then backward εymbolic execution (aε deεcribed below with reference to step 374 in FIG. 24) should be attempted to discover the address of the routine and translate it. In step 271, the opcode of the execution transfer instruction is again inspected to determine whether the path under investigation is a conditional branch. If not, then the path is followed. Otherwise, in εtep 272, an undecoded block iε created for the deεtination addreεs of the execution tranεfer for a conditional branch instruction, and a pointer to the basic block descriptor of the new block is placed in the list of undecoded blocks. The VAX instruction set includes a peculiar "CASE" inεtruction that iε more complex than conditional branch instructions. It iε theoretically possible to have a CASE instruction whose number of destinationε iε only known at runtime, but εuch an inεtruction iε untranslatable; therefore, the analyzer should mark it aε "untranslatable" so that the code generator will generate a call to the interpreter to interpret the CASE instruction. In the usual situation, the number of destinations for the CASE instruction will be known at translate time. All but one of these destinations can be queued in step 236 of FIG. 18, while the path can be continued from the remaining destination. A recurring problem, however, is that sometimes one of a multiplicity of destinations specified for the CASE instruction is irrelevant because it is never taken during execution. In this situation, the displacement for the irrelevant deεtination is usually zero. Therefore, in step 236 of FIG. 18, a special test should be made for the CASE opcode and a zero displacement path. If this condition is found, that CASE target is marked "untranslatable" so that it iε interpreted at execution time. Another recurring problem with the CASE inεtruction is that sometimeε the irrelevant path iε the "fall-through" path to the next inεtruction in addreεs sequence. In this situation the "fall-through" path might not contain translatable code, which will cause parsing and conversion errors in εtep 230 of FIG. 18. If parεing and converεion errorε occur, then the translator should issue an error message and discontinue following the thread (by continuing execution in step 238). For formulating the error message, the translator could look for a CASE statement preceding the instruction for which the parεing or conversion error occurred, and when found, diagnose the error as probably due to the CASE statement. Moreover, when discovered, these problems with the CASE statement may be recorded in the image information file generated by the translator for the original program. A flowgraph generated by the procedure of FIGS. 18- 19 is shown in FIG. 15. For a program named "DHRYSTONE", the initial entry point is at <main>, which has an address of 2E00 in the original program. The first two bytes are a VAX TM call mask, 0000, specifying that no extra registers are to be saved when DHRYSTONE is called, and that the exception-enable bitε IV and DV (integer and decimal overflow) are to be off (the default for C programs). In FIG. 15, this information is included in the firεt basic block represented by the hexagon symbol 301 for a procedure call. The next 9 bytes are a single basic block consiεting of two instructions, a SUBL2 (subtract longword) followed by a JSB (jump to subroutine). In FIG 15, this information is shown in the εecond baεic block represented by the rectangle 302 for a "normal" block. Upon encountering the JSB instruction, the tranεlator performε a look-up of an image information file, turnε the reference into offεet 0 in the image VAXCRTL, and looks in the file for information associated with the offset 0. The translator finds a normal return, and usage and setting of registers. Using this information, the translator builds a placeholder block, represented by the dashed oval 303 for a JSB placeholder, and (because of the uses JSB property) connects the placeholder to a new baεic block starting just after the JSB instruction, at addreεε 2E0B. Thiε baεic block consistε of a single CALLS instruction, and is represented by the rectangle 304. The translator calculates the destination addresε aε 2E18, and findε that it iε a procedure (ProcO) within the DHRYSTONE image, but the procedure has not yet been examined. The translator creates a placeholder for the procedure call, represented in the flowgraph as a dashed hexagon 305. Because the procedure has not yet been examined, the translator continues parεing instructions in the procedure, beginning at address 2E18. Eventually the translator decodes a RET in the procedure, indicating a normal return to address 2E12 in the main routine. The translator continues parsing beginning at 2E12, and finds a CVTWL (convert word to longword) inεtruction and a RET (return) instruction, which are included in a basic block represented in the flowgraph by a rectangle 306. The RET instruction terminates the main routine, so that the translator must continue with some other entry point in the DHRYSTONE program. Turning now to FIG. 20, there iε εhown a flowchart of a procedure for performing backward symbolic execution. In the proceεε of backward εymbolic execution, the deεtination addreεε for the execution tranεfer inεtruction iε repreεented by a εymbolic expreεsion, and the expression is εucceεεively modified to reflect the effect of each prior inεtruction. For example, suppose the execution transfer instruction is "JMP R6+4" which transfers execution to the absolute addreεε computed by adding four to the contents of a general purpose register R6. The computed destination addresε, for example, is represented symbolically as "R6+4". Suppose that in the backward direction through the program, the next instruction that referenceε R6 iε "MOVAB 4(R5),R6" which addε 4 to the contentε of a general purpoεe regiεter R5 and putε the εum into R6. Then the εymbolic expression "R6+4" is puεhed back through the prior "MOVAB 4(R5),R6" inεtruction to obtain the modified expreεεion "R5+8". The modified expreεεion has the same value before the prior instruction as the symbolic expresεion haε after the prior instruction. The proceεε of backward εymbolic execution continueε until either the computed destination addresε is resolved to an absolute or image-relative addresε, or a pr,ior instruction is reached which affects the value of the computed destination addresε but for which backward symbolic execution is not permitted. Backward symbolic execution is not permitted, for example, for certain instructions (such as XORB2 Rl,R2) for which backward symbolic execution is unable or unlikely to resolve the computed destination addresε. In thiε case it is convenient to reduce the computed destination addreεε to a symbolic value of "UNKNOWN" to indicate the possibility of missing code. Permitting symbolic execution for only a limited set of instructionε (εuch aε additionε, subtractions, loads, and storeε involving general purpose registers), however, allows the resolution of a large fraction of the computed destination addresses found in typical programs. When invoked in step 252 of FIG. 19, backward symbolic execution begins in εtep 321 of FIG. 20. In step 321, an attempt is made to convert the computed deεtination of the execution tranεfer inεtruction (recognized in εtep 235 of FIG. 18) to a predefined format of a symbolic representation of the destination addresε. The computed deεtination operand of an execution tranεfer inεtruction, for example, could have at leaεt the following formε, which are indicated in the table below by their aεεembler notation, with the name of their correεponding addreεεing mode. DESTINATION OPERANDS FOR A COMPUTED DESTINATION ADDRESS 1 . ( Rn ) Regi εte r Deferred 2. - ( Rn ) Autodecrement Autoincrement Autoincrement Deferred Byte\Word\Longword Displacement Byte\Word\Longword Relative Byte\Word\Longword Displacement Deferred Byte\Word\Longword Relative Deferred Register Deferred Indexed Autodecrement Indexed Autoincrement Indexed Autoincrement Deferred Indexed Byte\Word\Longword Displacement Indexed 14. @disp(Rn)[Rx] Byte\Word\Longword Displacement Deferred Indexed Although indexed addressing is commonly used for addressing tables and arrays, it is not commonly use for specifying a destination address for an execution transfer. Therefore one preferred format for symbolic expressions to represent destination addresεeε in a format capable of repreεenting all but the indexed addressing modes. Such a format is εhown in FIG. 21. It includeε a memory access flag 326 for indicating deferred addressing, a register number 327, and a longword displacement 328. The format may also include a register flag 329 that can be set to indicate that the register number 327 is valid, so that the format may also represent a longword constant. The register flag, for example, is set during step 321 of FIG. 20 and is reset if and when the process of backward symbolic execution finds a value for the contents of the register indicated by the register number and adds that value to the longword displacement. The addresε value indicated by the format in FIG. 21 is that value obtained by adding the displacement to the contents of the register when the register flag is set, or is the value of the diεplacement when the regiεter flag iε not εet, and when the memory acceεε flag iε εet, the εum or value is used as a addresε to fetch the address value from memory. Shown in FIG. 22 is a more complex format for a symbolic expreεεion capable of repreεenting all of the addreεεing modeε aεsociated with computed destination addresseε. Thiε format includeε a memory acceεε flag 331, an index regiεter flag 332, an index regiεter number 333, a εcaling conεtant 334, a base register flag 335, a base register number 336, and a longword displacement 337. The address value indicated by this more complex format is the value of the displacement, plus the value of the base regiεter when the base regiεter flag is set, pluε the εcaling constant times the value of the index register when the index register flag is set, and when the memory access flag is set, the εum iε uεed as an address to fetch the address value from memory. The more complex format of FIG. 22 would improve backward symbolic execution for finding destination addresεeε for execution tranεfer instructions that do not use indexed addresεing modeε, becauεe it would permit the proceεε of symbolic execution to account for the effects of more opcodes in the instruction set. For example, the format in FIG. 21 is incapable of representing the effect of a complement instruction upon the register specified by the register number. The format of FIG. 21, however, could use a signed offset number, and the effect of a complement instruction upon the index register specified by the index register number could be accounted for by complementing the offset number. To account for the effects of an even greater number of instruction operations, the symbolic expreεεion could use a variable length format εuch aε an alphanumeric character string including one or more numeric constantε; one or more register designators for designating the contents of each general purpose registerε εuch aε Rl, R2, R3, ... , R15; arithmetic operatorε εuch aε + and *; and a memory acceεε function €(x) representing the contents of memory at the addresε x, so that the value of the expression would be that value represented by applying the rules of algebra. A longword displacement deferred specifier such as @7(R1)[R4] is therefore represented as @(4*R4+Rl+7) . The offset constant of 4 for the index register R4 is determined by the longword mode of the specifier; the offset constant would be 2 for a word mode, and 1 for a byte mode. An offset constant of 1, however, would not need to be included in the character string. Other algebraic rules of simplification would apply, such as: x+A+B, where A and B are numeric constantε, εhould be εimplified to x+C, where C-A+B; x+Ry+Ry εhould be simplified to x+2*Ry; and @(z)+@(z)+x should be simplified to 2*@(z)+x. In step 321, an attempt iε made to reεolve the destination addresε for the execution tranεfer instruction by inspecting its destination εpecifier. This can be done for the relative and relative deferred addressing modeε. In the relative addresεing mode, the addreεε of the next instruction (i.e., the updated value of the program counter) is added to the displacement to provide the deεired destination address. In the relative deferred addressing mode, the addreεε of the next inεtruction iε added to the diεplacement to obtain an abεolute addreεε, and the contents of memory at this absolute addreεs (which should be in the fixup memory area 188 in FIG. 14) are fetched to provide the desired destination address. In step 322, when the destination addresε iε resolved, execution branches back to continue following the path in step 237 of FIG. 18. When the destination address is not resolved in step 321, then in step 323 an attempt is made to convert the destination specifier for the execution transfer instruction to a symbolic expression that, when evaluated at the beginning of the instruction, repreεentε the value of the deεtination addreεs. This is in contrast to the evaluation of the destination specifier itself, which occurs at the end of the instruction. For all but the autodecrement modes, the assembly language notation for the destination specifier converts directly by matching to the terms in the symbolic expresεion. For the autodecrement mode, the baεe register content is decremented by 1, 2, 4, 8 or 16 depending on the data-type of the instruction opcode before the base register content is used in evaluating the destination specifier. Therefore, when an autodecrement destination specifier is converted, the displacement constant in the εymbolic expression is -1, - 2, -4, -8 or -16 depending on the data-type of the opcode of the execution transfer instruction. Moreover, if the instruction architecture would permit autodecrement εource εpecifiers in an execution transfer instruction, then for each autodecrement εource εpecifier uεing the εame baεe register as a register included in the destination specifier, the diεplacement conεtant in the εymbolic expression would need to be decremented by -1, - 2, -4, -8 or -16 depending on the data-type of the opcode of the execution transfer instruction to account for the effect of each such autodecrement specifier. In step 324, execution branches to step 325 when the destination specifier cannot be converted to a symbolic expreεεion. Thiε occurε, for example, when the fixed format of FIG. 21 iε uεed for the symbolic expresεionε, and the deεtination specifier has an indexed addreεεing mode. In εtep 325 a warning is issued indicating that the execution transfer instruction has an unknown destination. When the destination specifier is converted to a symbolic expreεsion, some variables are initialized in step 341 to preform backward symbolic execution to search for posεible destination values for the εymbolic expreεεion. A liεt for receiving definite valueε iε cleared, and a flag for indicating the preεence of at leaεt one unknown value iε cleared. In addition, an "epoch" number iε incremented. The epoch number is used to mark each block for which symbolic execution has pasεed, in order to prevent infinite loops through the flowgraph. The possibility of infinite loops is illustrated by the flowgraph shown in FIG. 23. The flowgraph is drawn as a hierarchical data εtructure. The flowgraph, for example, haε an main entry point 342, and execution terminates at return instructions in terminal blocks 343, 344. Although there are no direct loops from the ends to the beginnings of any one block, there are paths 345 and 346 interconnecting intermediate blocks 347 and 348, which could cause infinite loops during hierarchical searcheε. A forward hierarchical εearch, for example, iε typically performed by calling a routine which beginε searching a block at its beginning, and if and when the end of the block is reached, the routine recursively calls itself for each succeεεor of the block; converεely, a backward hierarchical εearch iε typically performed by calling a routine which beginε εearching a block at is end, and if and. when the beginning of the block is reached, the routine calls itself for each predecesεor of the block. The presence of the paths 345 and 346 would cauεe either of these search routines to get caught in infinite loops, because the intermediate blocks 347, 348 would be alternately and repetitively searched. To prevent infinite loops during a forward or backward search, an "epoch number" is incremented prior to a search, and each time that the search routine iε entered for a block, the "epoch number" iε compared to an "epoch number attribute" for the block. A match between the "epoch number" and the "epoch number attribute" indicateε that the block haε already been reached during that search, and therefore should not be repeated. Returning now to FIG. 20, in step 351 a backward search is initiated for possible values of the symbolic expreεεion by calling a εearch routine in FIG. 24, aε further described below. Then in step 352 the "unknown" flag is inspected, and if it is set, a warning message iε iεεued in εtep 353 to warn of poεεible unknown values for the εymbolic expreεεion. In εtep 354 the liεt of definite values is inεpected; if it iε empty, the end of the path from the execution transfer instruction has been reached, and execution continues in εtepε 237 and 238 of FIG. 18 in an attempt to follow another path. Otherwise, in step 355, each definite value in the liεt iε teεted in the manner previouεly deεcribed above for εtepε 254 to 264 to insure that it iε a valid destination. As described above in connection with FIG. 27, however, some of these tests could be performed before the definite value is placed on the list so that the test can take into account the particular manner in which the definite value was obtained. Then step 356 checkε whether any of the definite valueε in the liεt are valid. If not, the end of the path from the execution tranεfer inεtruction haε been reached, and execution continueε in εteps 237 and 238 of FIG. 18 in an attempt to follow another path. Otherwiεe, εtep 357 checks whether the list includes more than one valid destination. If so, all but one are placed in the list of undecoded blocs (225 in FIG. 17), and the path is continued beginning at the remaining valid destination in stepε 237 and 239 of FIG. 18. Turning now to FIG. 24, there iε shown a flowchart of the backward search routine called in step 351 of FIG. 20. This routine has two entry points. A first entry point 361 is called to begin a new backward search at a specified instruction addresε in a εpecified block. A second entry point 362 is called to continue the backward search beginning at the end of a specified block. The first entry point 361 is called by step 351 of FIG.. 20 to begin a new backward search at the instruction address of the execution tranεfer inεtruction; in this case a first step 363 sets the epoch number attribute of the current block containing the execution transfer instruction equal to the epoch number for the new search. Then in step 364 the search in the current block is terminated if the current inεtruction addreεε iε the address of the first instruction in the block, which may occur if the block consiεtε only of the execution tranεfer instruction. Otherwise, in step 365, the current instruction address is changed to the inεtruction addreεs of the preceding instruction. These last two stepε 364, 365 are eaεily done by indexing the table (224 in FIG. 17) . When the second entry point 362 is called to continue the search at the end of a εpecified block, the epoch number iε compared in εtep 366 to the epoch number attribute of the block. When a new block is created, the epoch number attribute of the new block is set equal to the current value of the epoch number, which is incremented at the beginning of a new search. Moreover, the epoch number iε, for example, a longword, so that each time it iε incremented, it provides a unique value for each εearch during the translation of a given program. Therefore, in step 366, the epoch number of the current εearch will be equal to the epoch number attribute of the current block only if the current block has already been included in the current εearch. To avoid an infinite loop in the εearch proceεε and due to the reduced likelihood of finding any additional possible values, searching of the current block is terminated if SUBSTITUTE SHEET the current block has already been included in the current search. When the search iε to continue from εtep 366, the epoch number attribute of the current block iε εet equal to the epoch number in εtep 368. Then in step 369 the current instruction address is set equal to the addresε of the last instruction in the block. At this point the search procesε in FIG. 24 iε the εame regardleεε of whether the search routine is called from the first entry point 361 or the second entry point 362. In step 370 the expreεεion iε "puεhed" backward through the current inεtruction in an attempt to resolve the expression, as further described below with reference to FIG. 25. If the expresεion iε reεolved, aε teεted in εtep 371, the search of the current block iε terminated by returning from the backward εearch routine. If the expreεsion iε not reεolved, then stepε 364, 365, 370 and 371 are repeated to succesεively push the expresεion backward through the inεtructionε in the block until the expression is resolved or until the beginning of the block is reached. When εtep 364 finds that the expresεion haε been pushed to the beginning of the block, step 372 checks whether the expression representε a εubroutine argument. For the VAX TM architecture , an expreεεion repreεentε a εubroutine argument when iε in the form "@(R12 + C)" where C iε a conεtant. A call to an addreεε specified by an argument of the subroutine is known generally aε a "callback", which is a call to a procedure or function parameter. The "callback" is more particularly referred to aε callback, jεbback, or jmpback, depending on the opcode of the execution transfer instruction. When the "callback" is found, in εtep 373 the property iε noted in the image information file for the original program for use later for resolving any conflicts due to mutual dependencies between different programs, aε described below with reference to FIG. 31-33. A significant number of callbacks have been found, for example, in VMS TM syεtem service routines and compiled BASIC programs. Finally, in step 374, the search for possible valueε for the symbolic expression is continued by searching predecesεorε of the current block. If the predeceεεor is defined as a program entry point (i.e., a call from an external image), then information about parameter values from at leaεt one calling program image iε required in order to investigate whether any values for the symbolic expression might be determined by the calling program. Therefore image information files available to the translator are searched for information about parameter valueε that are paεsed to the program entry point. If the predeceεεor iε a placeholder, then placeholder information about the effects of the procedure or subroutine call will be referenced to determine whether those effects resolve the εymbolic expreεsion, in which case no further search of the predecessor is needed, or whether the procedure or subroutine call has no effect or a known effect on the symbolic expresεion, in which caεe backward symbolic execution can be continued to the predecessor of the placeholder. The placeholder information, however, may indicate that the subroutine affects the symbolic expresεion but in an unknown way. In thiε case backward symbolic execution could be performed beginning from each possible return in the subroutine that iε in the line of succession from the entry point defined by the placeholder. When the predecesεor iε a εubroutine call from a call εtatement in the image, then a search is made in the calling routine only when the "callback" property was noted in εtep 373. For VAX/VMS™ programs, it iε especially desirable to perform this search for a CALLS procedure call because in such a case the symbolic expression might be easily reεolved from an inεtruction that pushes the callback parameter on the stack. Also, the validity of the search into the calling routine can SUBSTITUTE SHEET be checked by comparing the callback parameter number N, where the symbolic expression is "@(R12+N)" or @N(AP) in assembler notation, to the number of parameters M actually put on the stack by the CALLS statement; this number M may be a short literal εpecifier of the CALLS instruction. Just before the CALLS statement, the procedure parameter is on the stack at a memory location of (N-4)SP. Therefore the effect of the CALLS operation upon the symbolic expression is accounted for by subεtituting SP for AP and εubtracting 4 from the expreεεion displacement when the expreεεion iε puεhed through the CALLS inεtruction. At the address of the CALLS instruction, the symbolic expreεsion to reεolve iε "@(Rl4+(N-4) )". The εearch may be initiated by a recurεive call to the second entry point 362 of the backward search routine of FIG. 24, after saving information that is needed by the backward search to continue the εearch of other predeceεεorε when execution returnε. The call and return could be coded aε followε: PRED BLOCK*- PREDECESSORS(BLOCK, PTRl) IF PRED_BLOCK(TYPE) - CALLX THEN (IF CALLBACK THEN (FOR EACH PREDECESSOR OF PRED BLOCK: CALLING_BLOCK «- PREDECESSORS(PRED_BLOCK, PTR2) IF CALLING_BLOCK(LAST_INSTR)= CALLS THEN (PUSH(BLOCK, EXPR, PTRl, PRED_BLOCK, PTR2) BLOCK <r CALLING_BLOCK CALL BACKWARD_SEARCH POP(BLOCK, EXPR, PTRl, PRED_BLOCK, PTR2) ) ELSE SET UNKNOWN_FLAG) ELSE SET UNKNOWN_FLAG) ELSE SET UNKNOWN FLAG If a predecessor is a normal block, then it can also be searched recursively as follows: IF PRED_BLOCK(TYPE) = NORMAL THEN PUSH(BLOCK, EXPR, PTRl) CALL BACKWARD SEARCH POP(BLOCK, EXPR, PTRl) After all of the predecesεor blockε are inspected or searched, the backward search routine is finished, and execution returns. Turning now to FIG. 25, there iε shown a flowchart of a routine for "pushing" a symbolic expresεion backward through a prior inεtruction to obtain a modified expresεion having the same value before the instruction as the symbolic expresεion has after the prior instruction. This routine, for example, iε called in step 370 of FIG. 24. This process is highly dependent on the instruction opcode. Instruction opcodes that do not directly affect the contents of memory or the general purpose registers other than the program counter do not affect the value of a symbolic expresεion including only constants, register designatorε, and a memory acceεs function. The changing value of the program counter in the usual case does not affect the value of the symbolic expression because before pushing the expresεion, the expreεεion doeε not have any register designator designating the program counter, and if the procesε of pushing the instruction through the expresεion would tend to add to the expreεsion a regiεter designator designating the program counter, it iε removed by substituting a definite addresε value. Instruction opcodes that are known to directly affect the contents of the general purpose registers or memory but which affect them in an indeterminate manner terminate the procesε with the finding of a symbolic value of "UNKNOWN". Due to the complex way in which may opcodes affect the contents of the general purpose registerε and memory, it iε deεirable to pre-εtore information regarding the effectε of each opcode in a decoding table addreεsed by the opcode. The decoding table could include the starting addresε of a separate routine written for each opcode. For the sake of illustration, however, the following description will show the common aεpects of routines for opcodes that perform similar functions, and therefore the decoding table organization in FIG. 26 includes a number of routines and opcode information that could be used by a more general procedure to branch off along various paths to perform specific actions for each opcode. It should be understood that εuch a general procedure could be expanded into a εeparate routine for each opcode by considering the paths taken in the general routine for each opcode. In the firεt εtep 381 in the flowchart of FIG. 25, the decoding table iε addreεsed to obtain an entry in the table. In step 382 the entry is compared to zerg to decide whether the instruction, by virtue of its opcode alone, cannot have any posεible effect upon the value of any permissible symbolic expression. If not, execution returns with the expression unresolved. A possible format for the decoding table is shown in FIG. 26. Encoded into a longword table entry 386 is a displacement to a special resolution routine for opcodes having unusual effects, a displacement 387 to a memory reference reεolution routine for the opcode, a displacement 388 to a register resolution routine for the opcode, and encoded information 389 about the data type and operands implied by the opcode. The encoded data for the opcode, for example, includes an implied register destination code 391, a data type code 392, a flag 393 to indicate an implied auto-decrement of the εtack pointer, a flag 394 to indicate an implied memory operation, and a flag 395 to indicate an implied auto-increment of the stack pointer. The implied regiεter code, for example, haε a value of 0 in the uεual caεe, a value of 1 to indicate that RO and Rl are affected, a value of 2 to indicate the RO to R3 are affected, and a value of 3 to indicate that RO to R5 are affected. The data type code indicates either byte, word, longword, quadword, or octaword. Returning now to the flowchart in FIG. 25, the expression is pushed backward through the sequence of intermediate operationε for the inεtruction. in reverεe order, these intermediate operations are auto-increment, opcode operation, and auto-decrement. In step 382 the instruction iε scanned for any auto-increment specifiers. For each express and implied auto-increment specifier using a register Rx that is designated in the expression, the register designator Rx in the expresεion iε replaced by Rx+C where C iε 1, 2 , 4, 8 or 16 depending on whether the opcode data-type is.byte, word, longword, quadword, or octaword, respectively, and the expreεεion iε simplified, where possible, by the multiplication and addition of constants. For example, if the expression iε "@(Rl+R7+4)+@(R3+3)+Rl+R6+7", the inεtruction includes an auto-increment εpecifier "(Rl)+", and the opcode data¬ type is quadword, then the expresεion iε changed to "§( 1+R7+12)+@(R3+3)+R1+R6+15". In step 402, execution branches to a εpecial regiεter resolution routine in step 403 when the value of the data from the decoding table iε not negative. To jump to the special resolution routine, for example, the following code could be used: MOVB 3(Rl),R2 ; Rl containε TABLE+4*OPCODE ADDL PC,R2,R2 JMP R2 An example of a εpecial regiεter reεolution routine iε the routine for CALLS deεcribed above with reεpect to step 374; if N<M*4, where M is number of parameters specified by the CALLS instruction, "R14-4" is εubstituted for the occurrence of R12 in the expresεion "§(R12+N)" and the expreεεion is simplified to obtain "@(Rl4+(N-4) )", otherwise a value of "unknown" is returned. In step 404 execution branches to step 405 when the expression has a memory acceεs operation. In step 405 an attempt is made to match the argument of each memory acceεε function to the addreεs of the expreεε or implied memory destination specifier for the instruction. If it is poεεible for a match to occur εuch that the value of the memory acceεε operation iε affected, then execution brancheε to εtep 406. In step 406, execution jumps to a memory resolution routine for the instruction opcode; the displacement to the memory resolution routine for a particular opcode, for example, is the "displacement for memory resolution routine" (387 in FIG. 26) in the decoding table. The memory resolution routines include routines for opcodes with implied memory destinationε, and routineε for,opcodes which may uεe expreεε memory destination result specifierε. Opcodeε with implied memory deεtinations, for example, include PUSHAB and PUSHL, which push an addresε or longword, reεpectively, upon the εtack. The implied memory deεtination εpecifier for either PUSHAB x or PUSHL x iε 0(SP), which specifies a destination address that is certain to match to a memory reference argument of the form "R14". When a match is certain, the following substitutions are made in the symbolic expresεion: εubεtitute x for the matching "@(R14)" term, and εubstitute "R14-4" for all Rl.4 register designatorε. An example of an opcode that may be found in an instruction having an express memory destination specifier is a data transfer instruction such as MOVL x,y where y is the memory deεtination εpecifier. In this caεe the reεult x of the inεtruction iε εubstituted for y in each matching memory reference argument in the expression. If the instruction is MOVL Rl,8(R2) and the expression is "@(R2+8)+Rl+7", for example, then the expresεion iε changed to 2*Rl+7. The matching of express memory destination specifierε to memory function argumentε iε alεo dependent on the opcode data-type. Inεtructions having quadword or octaword data-types, for example, may match to more than one. longword. The instruction CLRQ (Rx), for example, has a quad-word data type, and its memory destination specifier matcheε to "@(Rx)" and "@(Rx+4)" with the memory function being reduced to zero in each caεe. Alεo of interest is a possible match when there is a mis- alignment of addresses from longword addresε boundarieε; an example of thiε εituation iε the matching of the inεtruction CLRL (Rx) to "@(Rx+D", in which only one byte of the deεired longword addreεε iε reεolved to a definite value of zero. A deεign choice ariεes in step 406 when it iε possible but not certain for the address specified by a memory destination specifier to match the argument of a memory operation in the expresεion. An example of thiε εituation iε where the memory deεtination εpecifier is (Rl) and the expression has a memory acceεε function @(R2); a match would occur if the previouε inεtruction were MOVL Rl,R2. The memory deεtination εpecifier could be converted to another εymbolic expreεεion repreεenting the memory destination addreεε εpecified by the memory destination specifier, and backward symbolic execution could be performed in an attempt to convert this other symbolic expresεion to a form that iε certain to match or not match the argumentε of the memory operationε in the expreεεion. Performing backward εymbolic expression simultaneouεly for multiple expressionε repreεenting different deεtination addreεεes, however, complicateε the εearch becauεe additional epoch numberε and epoch number attributeε are required for each different deεtination addreεε. Therefore it would be deεirable to limit the extent of any εearch for multiple εymbolic expreεεionε, for example, by limiting it to one additional εymbolic expreεεion, or by limiting the search to one additional symbolic expression in the current block and its predecessors that are different from the current block. In any case, if a match is posεible but it iε concluded that the match is not certain, then the result of step 406 in FIG. 25 is to resolve the result, but not to a definite value. Execution therefore branches in step 407 to step 408 where the "unknown" flag is set, and execution returns. A symbolic expression may alεo be reεolved to a result of "unknown" where it is difficult or impoεεible to repreεent the effect of the inεtruction in the format of the εymbolic expreεεion. An example of thiε situation is an exclusive-or operation. Unleεs the prior instructions are performing a swap of the contents of two registers, the effect of the exclusive-operation will be indefinite. A εwap of regiεterε Rl and R2, for example, could be coded aε: XORL2 R1,R2 R2 «- Rl XOR R2 XORL2 R2,R1 Rl «- R2 XOR Rl XORL2 Rl,R2 R2 4- Rl XOR R2 In εtep 409 execution brancheε depending on whether εtep 406 resolveε the expreεsion to a definite value. An expresεion can be resolved to a definite value when all register designatorε with the exception of the program counter designator are eliminated from the expression. Therefore, whenever a register designation is removed or changed in a resolution routine, an attempt is made to resolve the expreεεion to a definite value. Thiε can be done by calling a routine εuch aε the one deεcribed below with reference to FIG. 27. When εtep 404 determineε that the expreεεion doeε not include a memory access function or when εtep 405 determineε that the inεtruction doeε not have a memory deεtination εpecifier that could poεεibly match, then it iε poεsible that the instruction may affect the contents of the general purpose regiεterε. In the uεual caεe, an inεtruction may affect the contentε of the general purpoεe regiεterε when it has an express register direct destination specifier, or when it has certain implied register direct destination specifiers. When an instruction has an express register direct deεtination specifier, however, it may affect registerε other than the expreεεly εpecified regiεter when the opcode ,data¬ type is quadword or octaword. Due to the rather complicated way in which the contents of registerε are affected by instructions, a decoding table could be used in which regiεter uεage maεkε are pre-εtored for the various possible combinations of opcode register usage, data-type and destination register number. The register usage mask could be fetched for the instruction and used to quickly determine whether the inεtruction can possibly affect the symbolic expression. For the encoding of opcode register usage information 389 shown in FIG. 26, for example, the address for the register decoding table could be formed from the byte of opcode register usage by checking whether a register direct destination iε specified for the instruction, and if so, appending the destination register number to the data type to form an index to the table of register usage masks. Each register usage mask is a word having bits set to indicate registerε that are affected, and bitε cleared to indicate regiεterε that are not affected by the inεtruction. Also in step 410, a register usage mask for the symbolic expression iε formed from a word by setting bits to indicate register designatorε uεed in the εymbolic expreεsion. Aεεuming, for example, that the most significant bit position is set or cleared to indicate the presence of R15 and the least significant bit position is set or cleared to indicate the presence of RO, then the register usage mask for the expresεion "@(R3+4)+Rl2+R4+3" would be 0001000000001100 2 . SUBSTITUTE SHEET In step 411 a logical AND is computed between the deεtination regiεter maεk of the inεtruction and the regiεter usage mask for the symbolic expresεion to reεult in a register conflict mask indicating the register designatorε in the expreεεion that may be affected by the instruction. In step 412 this register conflict maεk is compared to zero to decide whether a regiεter resolution routine for the particular instruction opcode should be used. If so, in εtep 413 the regiεter reεolution routine determineε whether the εymbolic expreεεion εhould be modified to account for the effect of the instruction opcode to possibly resolve the expresεion to a definite value, or whether the effect iε' indefinite so that the expression should be reεolved to a value of "unknown". If the instruction is a CLRL or CLRQ instruction, for example, each occurrence of each register designator indicated by the register conflict mask is removed from the symbolic expression. For a MOVL Rx,Ry instruction, the register designator for register Rx is substituted for each occurrence of the register designator Ry in the symbolic expression. For a MOVQ Rx,Ry instruction, however, each register Rz designated by the regiεter conflict mask is replaced with the register designator R[z+y-x]. In other words, Rx is substituted for Ry, but Rx+1 iε also substituted for Ry+1. If the expression is not resolved by the one of the reεolution routineε, then in εtep 414 the εymbolic expreεsion is "pushed" through any auto-decrement operations that may affect the regiεterε deεignated in the symbolic expression. For each express and implied auto-decrement specifier using a register Rx that is designated in the expression, the register designator Rx in the expression is replaced by Rx+C where C is -1, - 2, -4, -8 or -16 depending on whether the opcode data- type is byte, word, longword, quadword, or octaword, respectively, and the expression is simplified, where possible, by the multiplication and addition of constants. Although the "pushing" of expressions through instructions has been described generally with respect to complex expresεion formatε and complex inεtructionε, the proceεε of backward εymbolic execution haε .been found to be very useful for resolving computed destination addresseε in VAX/VMS M programε even though the εimple expreεsion format of FIG. 21 is used and the resqlution routines resolve a value of "unknown" unless the instruction is MOVAB, PUSHAB, MOVL, PUSHL, CLRL, CLRQ, or CALLS. Turning now to FIG. 27, there is εhown a flowchart of a routine for reεolving a term in a εymbolic expreεεion. The term, for example, iε represented in the fixed format of FIG. 21. In the first step 421 execution branches to εtep 422 if the regiεter flag is set; otherwise execution continues to step 423. In step 423 the register number is compared to 15. Unless the register number is 15 and therefore designateε the updated value of the program counter, the expression cannot be resolved. Therefore execution returns when the register number is not 15; otherwise, execution continues to step 424. In step 424 the destination addresε is computed as the sum of the displacement and the value of the updated PC. In the VAX™ inεtruction architecture, the proceεs of symbolic execution may add a PC register designator Rl5 to a symbolic expresεion when the current instruction has an expresε εource εpecifier of regiεter direct mode εpecifying the PC. In thiε caεe the value of the updated PC iε the addreεs of the byte immediately following the εpecifier that εpecified the PC in the current instruction. In step 425 the memory accesε flag iε inεpected. If the memory acceεε flag iε not εet, then the address should be a possible destination of the execution transfer inεtruction in the original program. For a VAX/VMS™ program, εuch a PC-relative addreεε εhould be in the instruction memory area (187 in FIG. 14) of the program. This is checked in step 426, and if the addreεs is found to be in the instruction area, the address is placed on the list of destinationε in εtep 427, and execution returns with the expresεion reεolved. Otherwiεe, a warning mesεage iε isεued in εtep 428. In addition, because an addresε outεide of the inεtruction memory address is considered invalid, it is not added to the list of destinations. Instead, the "unknown" flag is set in step 429, and execution returns with the symbolic expresεion reεolved. Execution brancheε to εtep 430 when the destination is a PC-relative indirect addresε. In a VAX/VMS™ program, a PC-relative indirect address is considered valid only when it is a fix-up vector contained in the fix-up vector area (188 in FIG. 14) of program memory. If the addresε computed in εtep 424 falls in the fix-up vector area of program memory and is included in the list or table of defined fix-up vectorε, then in step 432 the addressed fix-up vector is read from memory and in εtep 433 the fix-up vector iε placed in the list of destinations, and execution returns with the symbolic expression resolved. If the address computed in step 424 does not fall in the fix-up vector area of program memory or is not found in the list or table of predefined fix-up vectorε, then a warning iε iεεued in εtep 431, the "unknown" flag iε εet in εtep 429, and execution returnε with the εymbolic expreεεion reεolved. If the regiεter flag waε found to be clear in εtep 421 and the memory acceεε flag iε alεo found to be clear, then the deεtination iε an absolute address. For TM VAX/VMS programs, an absolute addreεε is considered valid only when it iε a predefined εyεtem vector entry point. Therefore in εtep 434 a look-up is performed in a list or table of predefined syεtem vector entry pointε. If the addreεs is a predefined system vector entry point, then in step 427 it is added to the list of destinations, and execution returns with the symbolic expression resolved. Otherwiεe, in εtep 435 a warning iε issued, in step 429 the "unknown" flag is set, and execution returns with the symbolic expresεion resolved. If step 422 finds that the memory flag is set, then the destination indicated by the symbolic expression is an absolute indirect addreεε. In a VAX/VMS™ program, εuch an addreεε iε conεidered to be invalid. Therefore, in step 436 a warning is isεued, in εtep 429 the "unknown" flag iε εet, and execution returnε with the εymbolic expreεεion reεolved. Turning now to FIGS. 28 and 29, there is shown a flowchart of a procedure that performε the εcan for plauεible code introduced above with reference to εtep 164 in FIG. 13 and the inεtruction memory area 187 of the program memory map 181 in FIG. 14. The result of this scan is to identify "plauεible code" areaε (197 in FIG. 14) in the instruction memory area (187 in FIG..14). In particular, the procedure in FIGS. 28 and 29 scanε areaε of the inεtruction memory area (187 in FIG. 14) that do not include the areas (194, 195, 196) of memory including decoded instructions that are included in the blocks of the flowgraph. The decoded instructions that are included in the blocks of the flowgraph are more succinctly called "known code". The areaε of the inεtruction memory area (187 in FIG. 14) that do not include known code will be referred to aε "unknown code areaε". The procedure in FIGS. 28 and 29 therefore εcanε the "unknown code areas" to find "plausible code". During the scan for plauεible code, a flowgraph of the plauεible code is built. When the scan for plausible code is finished, in a final step 499 of FIG. 28, the total number of bytes of known code (KNOWN_CODE) is computed by adding together the values of the "byte length" attribute in the basic block descriptors for all of the basic blocks in the flowgraph of known code, and the total number of bytes of plausible code (PLAUSIBLE CODE) is computed by adding together the valueε of the "byte length" attribute of the baεic block deεcriptorε for all of the baεic blockε in the flowgraph of plauεible code. Then the percentage of code found is computed according to: %_CODE_FOUND = KNOWN_CODE / (KNOWN_CODE + PLAUSIBLE_C0DE) Preferably the scan for plausible code recognizes legal instructionε in a variable-length inεtruction εet including inεtructionε that are contained in a variable number of addreεεable memory locationε in the program, and the scan switcheε between three different εcanning modeε. In a firεt εcanning mode (εtepε 500 to 510 in FIG. 28), the unknown code area iε scanned for legal instructionε εtarting at each and every addreεsable memory location in the unknown code area. When a legal instruction is found in the first scanning mode, the εcan switches to a εecond εcanning mode (εteps 511 to 518 in FIG. 28) of inspecting addresεable memory locationε immediately following the legal inεtruction found in the first scanning mode. The second εcanning mode εearcheε for a full block of instructions having of a serieε of consecutive legal instructionε up to and including an execution tranεfer inεtruction. If an illegal inεtruction iε found during thiε εecond εcanning mode, instruction is found during thiε εecond scanning mode, then the scan switches back to the first scanning mode, starting at the addresεable memory location immediately following the firεt addreεεable memory location of the legal instruction just previously found in the first scanning mode. If an illegal instruction is not found during this second scanning mode, then the scan switches to a third scanning mode (stepε 521 to 536 in FIG. 29) which checkε whether there iε a known valid destination addresε for the execution transfer instruction at the end of the full block, and if so, checks whether there is a valid instruction beginning at the known valid destination addreεε. A known deεtination addreεs is considered invalid when it is outside of the address range of the program, or when it is in the middle of a previously-found instruction of the program. If the third scanning mode concludes that there is a valid instruction beginning at the known valid destination addresε, then the full block iε considered to be plausible code. In the first step 500 in FIG. 28, a scan pointer for the first εcanning mode is set to the smalleεt addreεs in the instruction area of memory, and the variables PLAUSIBLE_CODE and KNOWN_CODE cleared. Then scanning begins in step 501. The table (224 in FIG. 17) is indexed by the εcan pointer to determine whether the εcan pointer points to known code. If so, then the scan pointer is successively incremented in εtep 503 until either the pointer falls outside the instruction area of memory as tested in step 504, causing the search for plausible code to end, or until the scan pointer points to unknown code. When the scan pointer points to unknown code, execution continues in step 505. In εtep 505 the contentε of the memory location addreεsed by the scan pointer are fetched and used as index to a heuristicε table having an entry which iε compared to zero to determine whether the firεt εcanning mode should skip the memory location addressed by the εcan pointer. When εcanning for VAX™ inεtructionε, for example, each addreεεable location holdε a byte of data, and the heuristics table in this case includes 256 different entries. The heuristics table is pre-programmed based upon the properties and characteristicε of the εpecific instruction architecture, typical data structures, and εystem architecture aεεociated with the program. If the inεtruction architecture haε privileged inεtructionε that are not permitted in user-mode programs, then the privileged instructions are skipped in εtep 506 (or otherwiεe conεidered illegal in εtep 510, if they cannot be detected by look-up in the heuristics table because they cannot be uniquely identified by the contents of a single addressable memory location). Data structureε and other areaε of a program which do not include instructions are often cleared. In this case, scanning in the first scanning mode should skip over any addresεable memory location containing all zeros. If the variable-length instruction architecture is highly complex, then it is rather unlikely that an instruction will be contained in a single addresεable memory location. The VAX TM inεtruction architecture lε εuch a case. In thiε caεe, εcanning in the firεt scanning mode should skip over an addresεable memory location having contents which are identified as an unlikely instruction contained in a single addresεable memory location. If moεt of the character data are repreεented in the program by codes that are also used in the instruction architecture, then the first scanning mode should skip over these codes that are likely to represent strings of character data instead of instructions. Preferably the first scanning mode skipε over any εtring of at least four printable ASCII characters. This test for a string of printable ASCII characters is performed in step 502. If εuch a character εtring iε found, the scan pointer iε incremented in εtep 503; otherwiεe execution continueε in εtep 507. In εtep 502, for example, the data contained at the program addreεε indicated by the εcan pointer, and at 1, 2, and 3 pluε the εcan pointer, are uεed to index a table including flags that are set to indicate printable ASCII characters, and are otherwise cleared. A character string iε found, cauεing execution to branch to εtep 503 rather than to continue to εtep 507, when the data contained at every one of these four program addresses are printable ASCII characters. Step 502 could therefore be coded as: X 4- CHARACTER_TABLE(PROGRAM(SCAN_POINTER) ) IF X.EQ.O THEN GO TO STEP_507 X <- CHARACTER TABLE(PROGRAM(SCAN_POINTER+l) ) IF X.EQ.O THEN GO TO STEP_507 X + • CHARACTERJTABLE(PROGRAM(SCAN_POINTER+2) ) IF X.EQ.O THEN GO TO STEP_507 X <- CHARACTER_TABLE(PROGRAM(SCAN_POINTER+3) ) IF X.NE.O THEN GO TO STEP_503 GO TO STEP 507 When a memory location is skipped over, the scan pointer is incremented by one address location in step 503. Possibly this will advance the scan pointer out of the unknown code area of memory. In step 504, this is tested by comparing the scan pointer to the maximum limit of the instruction memory area, and if the scan pointer is in the instruction memory area, by indexing the table (224 in FIG. 17) in step.501 to determine whether the scan pointer has advanced into known code. If the scan pointer is advanced out of the instruction memory area, then the scan for plausible code iε finiεhed, and the percentage of code found iε computed in the final step 499. If the scan pointer is in known code, then execution loops back to step 503 to increment the scan pointer by one memory location, to scan over the known code. If the εcan pointer iε in unknown code, then execution loopε back to step 505 to inspect the contents of the next unknown code memory location. When the unknown code is not εkipped over in step 506, then in step 507 an instruction decode pointer is set to the scan pointer, and in step 508 an attempt is made to decode an instruction. In step 509, for example, the opcode of the instruction is fetched and used as an index to a table holding the number of specifierε and decoding data for the opcode, and each specifier is fetched and decoded. In step 509, the instruction decode pointer is tested in a fashion similar to steps 502 and 504 whenever it is incremented during decoding to determine whether the inεtruction decode pointer is advanced out of the unknown code area of memory. If so, execution branches to step 503; otherwise, in εtep 510, execution also brancheε to step 503 if an illegal instruction opcode or illegal specifierε are detected during decoding. When steps 508 to 510 decode a legal instruction, then execution continues in the second scanning mode beginning in step 511. In step 511 the entry or entries in the addresε table (224 in FIG. 17) indexed by the addresε locationε of the decoded instruction and the table entries are marked to indicate the beginning of a plausible code instruction and any middle portions of the decoded inεtruction. Then in εtep 512 the addreεs table is alεo indexed with the address following the decoded instruction to determine whether it iε the addreεε of an already decoded inεtruction; if it iε, it εhould be the beginning of a decoded basic block, in which case the scan for plauεible code continues in step 535 of FIG. 29. Otherwiεe, the scan for plauεible code continueε in step 513 of FIG. 28. In step 513 the instruction decode pointer is incremented and an attempt iε made to decode another instruction. The decoding procesε is terminated, however, whenever the instruction decode pointer iε advanced out of the unknown code memory area, as tested in step 514, or whenever an illegal opcode or specifier is found, as tested in step 516. When the decoding procesε iε terminated in steps 514 or 516, the table (224 in FIG. 17) is cleared in step 517 of any indications of decoded instructions back to and including the addresε of the εcan pointer, and execution loopε back to step 503 to continue scanning in the first scanning mode. When a legal instruction is decoded in step 516 of the second scanning mode, then in step 518 execution branches back to step 511 unleεε an execution tranεfer inεtruction iε decoded, in an attempt to decode additional inεtructionε up to including an execution instruction. When an execution transfer instruction iε found in εtep 518, the third mode of the εcan for plauεible code beginε in step 521 of FIG. 29. Turning to FIG. 29, in step 521 the entry or entries in the table (224 in FIG. 17) indexed by the address locations of the execution tranεfer inεtruction, and the table entrieε are marked to indicate the beginning of a plauεible code inεtruction and any middle portions of the instruction. In step 522 the destination specifier is tested to determine whether it is a computed destination address; if so, then in step 523 backward symbolic execution may be attempted back to the scan pointer in an attempt to obtain a definite value for the destination. If an unknown value is obtained, as tested in step 524, then execution branches to step 517 of FIG. 28 to reject the full block of code back to the scan pointer and to continue scanning in the first scanning mode. In step 525 the destination addresε iε checked for validity, for example, depending on whether it iε an absolute or absolute indirect or relative or relative indirect addresε, aε εet out above in FIG. 27. Alεo, the deεtination addreεs iε conεidered invalid if it iε in the instruction area of memory but in the middle of a previously decoded known or plausible instruction, aε indicated by indexing the table (224 in FIG. 17). If the deεtination addresε iε invalid, then execution brancheε to εtep 517 of FIG. 28 to reject the full block of code back to the εcan pointer and to continue εcanning in the firεt εcanning mode. In step 526, the variable END_OF_BLOCK is set equal to the instruction decode pointer. In step 527, execution branches to step 528 if the valid destination is an external address. In step 529, execution also branches to step 528 if the valid deεtination iε at the addreεε of a previously decoded instruction, as indicated by indexing the table (224 in FIG. 17). When step 528 iε reached, the full block of code going back to the εcan pointer is validated as plausible code. Therefore in step 528 a block descriptor is created for the block of plauεible code. Included in thiε baεic block deεcriptor iε an attribute "byte length" εet to the number of byteε in the block, which iε .calculated aε one pluε the difference between the εcan pointer and the END_OF_BLOCK. When step 527 determines that the valid destination addresε is an internal addresε and εtep 529 determines that the internal address is not at a previously decoded inεtruction, then the deεtination addreεε muεt be in an area of inεtruction memory that iε not a previouεly decoded instruction. If an instruction can be decoded beginning at the destination address, then the previously decoded full block of code is considered to be plausible code; otherwise, the previously decoded full block of code is not considered to be plausible code. Therefore in εtep 531 the inεtruction decode pointer is set to the destination address and an attempt is made to decode an instruction. In steps 532 and 533 the decoding process is considered unsuccesεful if the inεtruction decode pointer iε advanced to a previously decoded instruction, or if an illegal opcode or specifier is decoded. Otherwise, when a legal instruction iε decoded, execution continueε to step 528, where a block descriptor iε created for the baεic block of code from the scan pointer to the address of the execution transfer instruction found in step 518 of FIG. 28. In step 530 an attempt is made to continue building a flowgraph of plausible code, beginning at the destinationε of the execution tranεfer inεtruction found in εtep 518 of FIG. 28. This is done by calling the flowgraph building routine of FIG. 18, beginning at step 236. Preferably, however, the plausible code flowgraph is not commingled with the known flowgraph, so that only known code is translated. Blockε of plauεible code, for example, are not be added to the liεtε of εuccesεorε and predecessors for blocks of known code, and blocks of known code are not added to the listε of predeceεsors and successors for the blocks of unknown code. In any event, the basic block descriptorε have an attribute identifying a basic block aε known code or plausible code. When the building of the flowgraph of plausible code terminates, it is still posεible that εome plauεible code waε not found by the flowgraph building proceεε. Therefore, in step 530, the scan pointer is set to END_OF_BLOCK. In addition, when step 512 of FIG. 28 finds that the execution path from the plausible code runs into a block of known code, scanning for plauεible code must also continue to find any more plausible code. SUBSTITUTE SHEET In this case, in step 535 the END_OF_BLOCK is set to the instruction decode pointer, and in εtep 536 a block deεcriptor iε created for the block of plauεible code from the scan pointer to the END_OF_BLOCK, but the flowgraph building step 530 is skipped; step 534 iε performed after step 536. At this point the third scanning mode is finished, and scanning is continued in the first εcanning mode in εtep 503 of FIG. 28. Turning now to FIG. 30, there iε shown a flowchart of a method for using the execution log file (88 in FIG. 9) to assist in locating untranslated instructionε in the original program. Aε introduced above, and aε shown in step 541 of FIG. 30, an original program is translated, and the translator generates an image information file for the program. Then in step 542 the translated program is executed (by the RISC computer 50 in FIG. 9) in conjunction with the interpreter and the original program. During this execution, information is recorded in the execution log file whenever execution switcheε from the translated program to the interpreter in order for the interpreter to determine a computed destination address to untranslated code. The interpreter, for example, records information identifying the origin address in the original program of the execution transfer inεtruction having the unreεolved computed deεtination address, and the value computed for that destination address in the original program. Preferably this information is in the form of a pair of the origin and destination addresseε in the original program. After execution of the tranεlated program in εtep 542, the execution log file is inspected in step 543 to determine whether the interpreter was called and determined the location of any untranslated code. If so, then in step 544 the original program is retranslated using the image information file for the program, and the execution log file. Before building the flowgraph, for example, the destination addresseε in the execution log file are added to the liεt of 225 of undecoded blockε. After building the flowgraph, the predeceεsors of any blocks beginning at the unresolved entry points are inspected to determine whether they include blocks including the respective origin addresses; if not, then linkages to the predecesεorε are added and backward symbolic execution is re-iterated through these new linkages. Therefore the translator may use the origin addresεeε as well as the destination addresses to investigate possible execution paths in the original program including paths that were not discovered during the first translation of the original program and were not taken during execution of the translated program or interpretation of the untranslated portions of the original program. To aid in the succeεsive re-translation of a program, the flowgraph data structure (211 in FIG. 17) and table 224 in the converted program could be stored in a file. In this case, re-translation could begin where the building of the original flowgraph terminated. To continue building the flowgraph, the table 224 iε indexed with the origin addreεεeε to find the blockε including them. Then the deεtination addreεεeε from the execution log file are loaded into the queue (225 in FIG. 17) together with a list of predecessors including the blocks containing their respective origin addreεεeε. Then the building of the flowgraph iε restarted at the first step 229 in FIG. 18. After the original program iε re-translated in step 544, the retranslated program is executed in step 542. Preferably thiε feedback of information from execution to re-translation iε performed after each execution, of the tranεlated program εo that all of the instructions in the original program that are actually located will be translated. Turning now to FIG. 31, there iε εhown a procedure for translating mutually dependent programs in situations where it iε undeεirable or impoεsible to translate the programs at the same time, for example, in a situation where the data structures shown in FIG. 17 would greatly exceed the capacity of random acceεε memory in the computer performing the tranεlation. Two programε are mutually dependent when they call each other. These mutual dependencies often interfere with the process of locating and translating instructionε in the program. In particular, return pointε must be properly connected, which requires information about the image being called. Aε introduced above, image information fileε generated or updated during tranεlation of original programε are used to store information about the effects of calling each available entry point in the programε. When tranεlating an image, a call to an entry point in another image is translated by using the information recorded about the effects of calling that entry point. Mutual dependencieε, however, may create a εituation where the effects of calling an entry point in a second image are dependent on the first image, and are not known until the first image is translated. But the tranεlation of the firεt image may require information about theεe effects of calling the entry point in the second image. Such conflicting mutual dependencieε ariεe, for example, in a caεe where the firεt image calls the entry point in the εecond image and paεεeε a procedure-parameter identifying the addreεε of a procedure in the first image, but the second image then calls back to the procedure of the firεt image. To tranεlate the firεt image, information about the effectε of calling the entry point in the second image should be known, such aε the fact that the εecond image calls back the first image. This information, however, cannot be determined by examining the first image. To translate the second image, information about calling the first image should be known such aε the εet of possible values of the procedure-parameter passed during the call-back to the first image, and the effects of the call-back for each poεεible value of the procedure parameter. This information, however, cannot be determined by examining the second image. Therefore a conflicting situation ariseε where each image should be translated before the other image for the translationε to have all of the required information. Aε εhown in FIG. 31, the conflict due to mutual dependencies is resolved by multiple translationε. During the tranεlation of a firεt program (PROGRAM#l) in εtep 551, the tranεlator findε that there iε no information regarding the effects of calling the entry points of a second program (PROGRAM#2), because the second program has not yet been tranεlated. The tranεlator therefore makeε default aεεumptionε about the calls to the entry points of the second program, such aε a normal return and no callbackε. When the εecond program iε tranεlated in εtep 552, the tranεlator determineε that the εecond image doeε have call-backε, which iε contrary to the default aεsumptions. As shown in stepε 553 to 557 in FIG. 31, a proceεε of iterative retranεlation could be uεed in which the image information fileε are uεed to paεs new information discovered during the prior translation of one program to the retranslation of the other. Steps 555 and 556 terminate the process of iterative retranslation when a condition of strict convergence occurs. Strict convergence occurs when each of the two programs is retranslated in alternate sequence until no change occurs in the image information files. Convergence, however, can be assured with fewer translations by senεing when no relevant changeε have occurred in the image information fileε. An assumption underlying the simplification of the test for strict convergence is that a second translation of an individual program will not change when it is retranslated with its image information file generated during its initial translation. With this asεumption, one may conclude that the translation of the second program will affect the retranslation of a first program only if image information about the second program changes in a way that is relevant to the tranεlation of the first program. Turning now to FIG. 32, there are shown in FIG. 32 an. image information file 561 for the first program and an image information file 562 for the second program just after the initial tranεlation of the firεt program and initial translation of the second program. The image information file 561 for the first program includes information about first program entry points (ENTRY A, ENTRY B, ENTRY C, ENTRY D, ...) investigated during initial translation of the firεt program. This information may include, for each entry point, the address of entry point, and any callback parameters associated with that entry point, that were discovered in step 372 of FIG. 24 and recorded in the image information file 561 in step 373 of FIG. 24 during tranεlation. In addition, the image information file 561 includes information 564 about calls (CALL Q, CALL S, CALL Y, CALL Z) from the first program to external entry points in other programs, which was recorded in the image information file 561 in steps 256, 258 or 259 of FIG. 19 during translation. This information may include, for example, the external destination address of the call, the type of call (e.g., CALLS or CALLG), the number of parameterε associated with the call, and any definite values of the parameterε. Definite valueε of the parameterε, for example, might be obtained by backward εymbolic execution from the call inεtructionε. In a εimilar faεhion, the εecond program includes information 565 about calls (CALL A, CALL B, CALL H, CALL K) from the second program to external entry points in other programs, and information 566 about program entry points (ENTRY Q, ENTRY R, ENTRY S), obtained during the initial translation of the second program. Conεider now whether the first program would change if it were retranslated with the benefit of the information in the image information file 562 of the second program. By matching the addresεeε of the program entry points in information file 561 for the first program with the addresεeε of the external callε in the image information file 562 for the second program, and by matching the addresεeε of the external callε in the image information file 561 for the firεt program with the addreεses of the program entry points in the image information file 562 for the second program, the relevant external callε and entry pointε in the image information file 562 for the second program are identified. If the information about these external callε and program entry points in the image information file 562 for the second program differ in any way from the default assumptions that could affect a retranslation of the firεt program, then the first program should be retranslated. Moreover, if the image information file 562 has external calls (such as CALL K in FIG. 32) to program #1 that call an untranslated code location in the first program, then the first program should be retranslated, using the address of the untranslated call location as an initial unresolved block entry point. In addition to external calls to untranslated portions of the program under consideration for retranslation, particularly relevant changes include new definite values for call parameters for external calls to entry pointε in the program under consideration for retranεlation because these definite values may be used during retranslation by backward symbolic execution to resolve a destination addresε to untranslated code in the other program, and new callback parameters for program entry points called by the program under consideration for retranslation because backward symbolic execution of these callback parameters during retranslation may resolve to values of new program entry points in untranslated code in the program under consideration for retranslation. Turning now to FIG. 33, there is shown a flowchart of a procedure for the alternate iterative translation of two original programs that obtains fast convergence by performing retranslation of one program only after there has been a relevant change in the content of the image information file for the other program. The firεt step 571 and the second step 572 are the same as the first step 551 and the second step 552 in the procedure of FIG. 31. In the third εtep 573 of FIG. 33, however, the relevant entries in the image information file (562 in FIG. 32) for the second program are inspected for any changes from the default assumptions that might possibly affect retranslation of the first program, aε discussed above with reference to FIG. 32. If any such changeε are discovered, then the first program is re-translated in step 574; otherwise, no re-translation of the firεt program or the second program is needed. During the re-translation of the first program in step 574, changeε made to the external call and program entry point information in the image information file for the first program are noted, for example by flagging the changed entries and keeping copies of the old entries, or by flagging new entries. After the re-translation of the first program, then in step 575 the relevant changed entries in the image information file (561 in FIG. 32) for the firεt program are inspected for any changes that might possibly affect retranslation of the second program, as discussed above with reference to FIG. 33. If any such changes are found, then the second program is re-translated in step 576; otherwise no re-tranεlation of the first program or the second program is needed. During the re-translation of the second program in step 577, changes made to the external call and program entry point information in the image information file for the εecond program are noted, for example by flagging the changed entrieε and keeping copieε of the old entrieε, or by flagging new entrieε. After the re-translation of the second program, then in step 577 the relevant changed entries in the image information file (562 in FIG. 32) for the second program are inspected for any changes that might possibly affect retranslation of the firεt program, as discussed above with reference to FIG. 32. If any such changes are found, then the first program is re¬ translated in step 574; otherwise no re-translation of the first program or the second program is needed. This procesε of multiple tranεlationε and checked assumptions may iterate a number of times, but eventually the process will converge. In many caseε, the proceεε will converge upon an accurate deεcription of each image, and then further retranεlation will not be neceεsary. A runtime library, for example, typically includes a collection of images that have mutual dependencies among themselves, but which are called by user programs at εpecified entry points and do not have mutual dependencies with the user-programs. In this case the process of multiple translationε and checked aεεumptionε will converge upon an accurate deεcription of each image, including complete information about the effectε of calling each image at the specified entry points. A file including thiε information can be uεed for the translation of user programs, without requiring any retranslation of the runtime library images. Although the invention haε been deεcribed above in connection with a CISC-to-RISC code translator, the invention is alεo very uεeful for tranεlating CISC code of one programming language to CISC code of another programming language, for example, to tranεport a program from one kind of digital computer to another kind of digital computer, or to tranεport a program from one kind of operating system to another kind of operating syεtem. Moreover, the analysiε and error checking featureε of the invention can be uεed for teεting and debugging a program without tranεlating it. APPENDIX A INTERMEDIATE CODE REPRESENTATION Data Accesε Tuples 1. LITREF (Literals) Literals values are represented with LITREF tuples, whose reference attributes point to literal nodes in the symbol table. The node may be for a named literal (such as SYM$LOFFSET) , or a conεtant εuch aε zero or one. A LITREF may only appear aε a εource operand. Exampleε: 2. REGREF (Registerε) Direct regiεter referenceε are repreεented with REGREF tupleε. Theεe contain only a register number attribute, and can be used directly either as source or destination operands. In the tuples, the register number is not the register number used in the source; it is one of the εet of ratu_reg_k_* constants, which are defined for the RISC computer registers R0-R31, AP, FP, and SP. The REGREF tuple has a symbol node attribute which can be used to associate a symbolic name with this regiεter instance. It also has attributes uεed .by the code generator. 3. MEMREF/FETCH (Non-symbolic Memory Referenceε) Moεt operandε in MACRO code are memory referenceε through regiεterε. The MEMREF tuple is used to represent these, and has two components; a base register operand, and an optional offset operand. The baεe regiεter operand is always the address of a REGREF tuple. If present, the offset operand is a pointer to either a LITREF, SYMREF, or COMP_OP tuple. If the offset operand is not specified, an offset of zero is asεumed. The value of a MEMREF tuple iε the addreεs of the specified memory location. To refer to memory in a εource operand, a FETCH tuple εhould be uεed to indicate the value at the location iε needed. MEMREF can be uεed directly as a destination operand, or as the source in a MOVAx or similar instruction. This implies that the MACRO compiler front end will need to distinguiεh addreεε-context referenceε from value-context referenceε, which could be a straightforward table lookup on instruction type and operand number. For modify operands, such as the designation of an INCL instruction, the addresε-context form εhould be uεed. FETCH iε alεo uεed on IDXREF and SYMREF tupleε, deεcribed below: The MEMREF tuple containε three flagε which may be set to further qualify the referenceε: • DEFERRED, which indicateε an additional level of indirection. For example, @offεet(Rn). • AUTOINCREMENT, which indicateε a poεt-increment of the baεe regiεter. • AUTODECREMENT, which indicateε a pre-decrement of the baεe regiεter. Thiε cannot be specified with DEFERRED, or with AUTOINCREMENT. SP, FP, and AP based references are all represented as MEMREF operands. The MEMREF tuple has a symbol node attribute which can be used to associate a symbol name with this memory location. It alεo haε attributeε that can be uεed by the code generator to optimize multiple references to the same base location. Examples: Source Intermediate Representation pushl (rO) LOl L02 L03 L04 puεhl e(r0)+ LOl: L02: L03: L04: popl 4(r0) LOl L02 L03 L04 puεhl @foo(sp) LOl L02 L03 L04; L05: 4. SYMREF (Symbol Table Reference) The SYMREF tuple is used for representing a reference to an item with a symbolic name. The name "SYMREF" should be understood to mean "SYMbol table REFerence" rather than "SYMbol node REFerence," because the εymbol table node it pointε to may be a Symbol Node, External Node, Label Node, or Routine Node. The value of the tuple iε the value of the symbol. For Symbol nodes, this implies that a FETCH is not used to get the symbol'ε value. Symbol nodeε are like Literal nodeε in thiε reεpect; they are εimply symbolic names for some compile-time value. For External, Label, and Routine nodes, a FETCH may be required depending on the context. An address or immediate mode reference will not require a FETCH. (Immediate mode references are only legal on Externals). For value references, a FETCH of the SYMREF is required. For example, a branch to an External, Label, or Routine will use the SYMREF directly. A MOVL instruction of the value at some Label, for example, will uεe a FETCH of the SYMREF. A DEFERRED flag in the SYMREF tuple can be uεed to indicate indirection. Thiε flag iε only usable on SYMREFs of External and Label nodeε. Examples: Intermediate Representation LOl: symref [foo_label] L02: data.addr (LOl) LOl L02 L03 Label And Entry Point Tuples 1. LABEL A LABEL tuple representε a branch target within a routine. The label εymbol to which it referε is also pointed to by SYMREF tuples uεed aε target operandε of branch tuples. Labels declared with the UNWINDJTARGET directive in the source are represented with normal LABEL tuples. An UNWIND_TARGET flag iε εet in the tuple, however. Examples: Source Intermediate Representation foo: pushl #0 LOl L02 L03 foo:: .unwind target LOl: label [foo, unwind target] 2. JSB_ENTRY, CALL_ENTRY, IO_INTERRUPT_ENTRY, EXCEPTION ENTRY Entry Point Directive tuples flag the start of routineε declared with one of the JSB_ENTRY, CALL_ENTRY, IO_INTERRUPT_ENTRY, or EXCEPTION_ENTRY directives in the source. The tuple points to an MTU Entry node for the declared routine. The MTU Entry node. contains the register usage and other information specified in the source directive. Examples: Source Intermediate Representation foo:: .jsb_entry LOl: jsb_entry [foo] foo:: .call_entry LOl: call_entry [foo] Control Flow Tuples 1. BRANCH BRANCH tuples specify a branch to either a specific target label, or an indirect branch through a memory location. The first operand must be the address of either a SYMREF tuple identifying a Label Symbol node, or a value-producing tuple specifying the branch addresε (REGREF or FETCH) . BRANCH tuples are used for BRB, BRW, and JMP instructions. Note that for the indirect branch case, the code generator will produce a JSB rather than a branch. Examples: Source Intermediate Representation SUBSTITUTE SHEET brb foo LOl: symref [foo] L02: branch (LOl) jmp bar LOl: symref [bar] L02: branch (LOl) jmp 4(R10) LOl: litref [#4] L02: regref [rlO] L03: memref (LOl, L02) L04: fetch (L03) L05: branch (L04) 2. CALLS/CALLG CALLS and CALLG tuples correspond to a VAX™ call instruction to the routine εpecified in the firεt operand, which iε a εymbol or memory reference. The second operand is either a parameter count (for CALLS) or the addresε of the parameter liεt for CALLG. Exampleε: Source Intermediate Representation callε #2, foo LOl L02 L03 callg (ap), (rlO) LOl L02 L03 L04 L05 3. RETURN The RETURN tuple correεpondε to a VAX™ return instruction. SUBSTITUTE SHEET The analyzer will further tag the RETURN tuple with a symbol node for the routine being returned from, and with a flag indicating whether the interpreter must be called to emulate the return. Examples: Source Intermediate Representation ret LOl: return 4. JSB The JSB tuple correspondε to a VAX M JSB or BSBx inεtruction. It has a single operand which is either a SYMREF pointing to a symbol node address, or a value producing tuple representing an indirect JSB target. Examples: Source In ermedia e R re entation bsbw foo jsb (rlO) 5. RSB/REI The RSB and REI tuples correεponds to a VAX .TM RSB and REI instructions, respectively. The analyzer will further annotate theεe tupleε with a pointer to the symbol node for the routine being returned from. Examples: Source Intermediate Representation rsb LOl: RSB 6. CONDBR The CONDBR tuple iε uεed to repreεent all VAX™ conditional branch inεtructionε. The tuple has an opcode attribute (specifying the VAX TM branch opcode), and a destination operand which is the addresε of either a SYMREF tuple pointing to a symbol node, or a value- producing tuple representing an indirect destination. The presence of additional optional operandε iε dependent on the conditional branch type. For example, BLEQ would have no additional operandε, while BLBC would have an operand εpecifying the item to be teεted, and BBS would have two additional operandε. The following table εhowε the conditional branch typeε and required additional parameterε. The Type column indicateε the allowed operand typeε for the operand; "Value" indicateε that LITREF, SYMREF (of compile time Symbol), COMP_OP, REGREF, and FETCH (of SYMREF, MEMREF, or IDXREF) are allowed, while "Addr" 38 156 indicateε that REGREF, SYMREF, MEMREF, and IDXRE F are allowed. O perand 1 iε alwayε the branch deεtination. bbε #<baεe+bit., rO, 4(rl0) Inεtruction Tupleε 1. INSTR The INSTR tuple iε the way all other MACRO inεtructionε are repreεented. Itε inεtruction attribute iε a conεtant εignifying the opcode, and itε operandε repreεent the inεtruction operands. The opcode constant is normally one of the mtu_vax_k_* values, which represent VAX TM opcodes. It may also be one of mtu_evax_k_*, which repreεent built- ins for RISC-specific opcodes. The set of operand types allowed iε inεtruction dependent. In general, LITREF, SYMREF, COMP_OP, REGREF, and FETCH (of SYMREF, MEMREF, or IDXREF) operatorε are allowed for operandε whoεe values are uεed, while REGREF, SYMREF, MEMREF, and IDXREF are allowed for operandε whoεe addresses are used. For "modify" type operands, such as the deεtination in an "INCX" inεtruction, the address form should be uεed. The INSTR tuple haε condition code uεage flags which provide the code generator with this information computed by the analyzer. They will specify whether the N and Z, C, and/or V bit values must be εimulated by the code generated by the current instruction. An additional "local NZ" bit is εet if the only uεe of N/Z iε by one or more conditional branch inεtructionε which immediately follow. This allows the code generator to use the result value directly, in some caseε. Examples: Source Intermediate Repreεentation incl 4(r0) LOl L02 L03 L04 addl3 rO,foo$l_value, (εp)+ LOl; L02: [foo$l value] L03 L04 L05 [autoincrement] L06: move5 LOl L02 L03 L04 L05 L06 L07 [foo$w buf len] inεque 8( rO) ,foo$q_head

Claims: WHAT IS CLAIMED IS: 1. A method of operating a digital computer to analyze a series of instructions in a computer program; each of said instructionε having a reεpective program addreεε in εaid computer program; εaid computer program including instructions that transfer execution to specified addresses and that together with the program addresses of said instructionε define an execution εequence for εaid instructions, said instructionε alεo including inεtructionε that εpecify operationε that modify contents of memory at specified memory addresεeε, and instructions that specify operations that modify contentε of εpecified general purpoεe regiεters, said program including at least one execution transfer instruction specifying a tranεfer of program execution to a deεtination address in said program determined from contentε of a εpecified one of εaid general purpoεe regiεterε; εaid method compriεing a εearch for at least one value for said destination addreεε prior to program execution by the εteps of: a) forming an expresεion of said destination address in terms of the contents that a designated one of said general purpose registers will have during program execution; b) inspecting, in reverse order of εaid execution εequence, inεtructions in εaid execution sequence that precede said execution transfer instruction, and (1) when an inspected inεtruction εpecifieε modification of the contentε of a general purpose register deεignated in said expresεion but does not specify a modification such that said expression expresεeε a value that is definite with respect to the addreεε of said inspected instruction, modifying said expreεεion to account for the εpecified modification εo that εaid expreεεion expreεses said destination address in terms of contents that at least one general purpose register designated in εaid expreεεion will have during program execution when program execution reaches the program address of the inspected instruction; and (2) when an inspected instruction εpecifieε modification of the contentε of a general purpose register designated in said expression εuch that said expreεsion expresεeε a value that iε definite with respect to the addresε of εaid inεpected inεtruction, determining said value for said destination address from said expresεion . 2. The method as claimed in claim 1, wherein said expression includes a memory accesε function expreεεing said destination address in terms of the contents of memory at a memory address specified by a memory accesε argument expreεεion, and wherein εaid method further includes the step of attempting to match the memory accesε argument expreεεion to a memory address specifier in the inspected inεtruction when the inspected instruction modifies the contents of memory at a specified memory addresε, and when a match occurε, replacing the memory acceεε function in εaid expression with an expresεion of the modified contents of memory at the specified memory address. 3. The method as claimed in claim 2, wherein εaid εtep of attempting to match the memory acceεε argument of said expression to a memory addresε εpecifier in the inspected instruction includes searching instructionε preceding said inspected instruction to find an instruction that sets said memory addresε εpecifier to a form of expression matching said memory access argument expresεion. 4. The method aε claimed in claim 1, further comprising the step of attempting to match said expresεion to a predefined expreεεion format for a εubroutine argument paεεed to a εubroutine during a εubroutine call operation, and when a match occurε, recording that a callback may occur to εaid εubroutine argument from εaid execution tranεfer inεtruction. 5. The method aε claimed in claim 1, further compriεing the εtep of attempting to match εaid expression to a predefined expresεion format for a εubroutine argument of a εubroutine call inεtruction when the addreεε of the inεpected inεtruction iε a destination addresε of the subroutine call instruction, and when a match is found, continuing εaid εearch by inεpecting, in reverse order of said execution sequence, instructions in said execution sequence that precede said subroutine call instruction. 6. The method as claimed in claim 5, wherein said subroutine argument is stored in memory on a stack having a memory address indicated by the contents of a stack register, εaid εubroutine call inεtruction sets an argument pointer register with a value indicating a memory addresε of the εubroutine argument, and wherein εaid expresεion is modified to account for the effect of the subroutine call instruction by substituting a deεignation of the stack register for a designation of the argument pointer regiεter. 7. The method aε claimed in claim 5, wherein εaid subroutine call instruction pasεeε a number of subroutine arguments and includes a specifier specifying the number of subroutine arguments, and wherein the predefined expression format for an argument of said subroutine is dependent upon the specified number of εubroutine argumentε. 8. The method aε claimed in claim 1, wherein said step of determining said value for said destination address from said expresεion includeε the εtepε of computing the estination address from the program address of the inspected instruction when the inspected instruction includes a register specifier specifying a program counter register. 9. The method as claimed in claim 1, wherein εaid expression is stored in a fixed format including a memory accesε function flag, a regiεter deεignation number, and a displacement constant. 10. The method aε claimed in claim 1, wherein εaid expreεsion is stored in a variable-length format including a string of characters selected from a predefined set of register deεignatorε, operatorε and numerical constants. 11. The method as claimed in claim 10, wherein said operators include addition, multiplication, and a memory accesε operation. 12. The method aε claimed in claim 10, wherein said modifying said expreεεion includeε εubεtituting in said expression a new expresεion for each occurrence of a regiεter deεignator deεignating a regiεter εpecified by a regiεter specifier of said inspected instruction, and then simplifying the expression by applying rules of algebraic simplification. 13. The method as claimed in claim 12, wherein said expresεion expreεεeε a value that is definite with respect to the addresε of εaid inspected instruction when said expresεion εimplifieε to an abεolute or program- counter relative program addreεε. 14. The method aε claimed in claim 1, further compriεing the εtep of validating said value for said destination address after said value is determined from said expression, and wherein εaid validating teεtε whether εaid deεtination address has an access mode that is either abεolute, absolute indirect, program-counter relative, or program-counter relative indirect, and rejects as invalid destination addresses that do not fall within a respective predefined set of valid addresseε for each access mode. 15. The method as claimed in claim 1, wherein said instructions include instructionε having opcodeε, auto- increment εpecifiers, and auto-decrement specifiers, and wherein said step of modifying said expresεion to account for the εpecified modification of the contentε of εaid designated one of said general purpose registerε comprises the following stepε in εequence: (i) for each auto-increment specifier in the inεtruction that specifieε an auto-increment register designated in the expression, incrementing a displacement in the expreεεion that iε associated with the auto- increment register designated in the expresεion; and then (ϋ) for each operation εpecified by an opcode in the instruction that modifies the contentε of a general purpoεe regiεter deεignated in the expreεεion or that modifies a memory location indicated by a memory accesε argument in the expreεεion, modifying εaid expreεεion to account for the modification by the opcode; and then (iii) for each auto-decrement specifier in the instruction that specifies a auto-decrement register designated in the expression, decrementing a displacement in the expresεion that is asεociated with the auto- decrement regiεter deεignated in the expreεεion. 16. The method aε claimed in claim 1, wherein εaid εtep of inεpecting further includeε: (3) when an inεpected inεtruction εpecifieε a modification of the contents of a general purpose registerε deεignated in the expreεεion but εaid modification is a predetermined kind of modification that cannot be accounted for by modifying said expresεion in a predetermined way, determining a value of "unknown" for εaid expreεεion and terminating the inεpecting of inεtructionε that precede εaid inspected instruction. 17. The method as claimed in claim 1, wherein said step of inεpecting further includes: (3) when an inspected instruction specifieε a modification of the contentε of εaid designated one of said general purpose registers and said inεpected inεtruction haε an opcode in a predefined εubεet of instruction opcodes for which modification of said expresεion iε not permitted, determining a value of "unknown" for εaid expression and terminating the inspecting of inεtructionε that precede said inspected instruction. 18. The method aε claimed in claim 1, wherein εaid εtep of inεpecting further includeε: (3) when an inεpected inεtruction haε an opcode in a predefined εubset of instruction opcodes which modify neither the contentε of the general purpoεe registers nor addresεable memory locationε, diεcontinuing the inεpecting of the inεtruction without any modification of εaid expreεεion to account for any effect of the inεtruction and without determining any value for εaid destination address from said inspected instruction. 19. The method as claimed in claim 1, wherein said execution εequence includes a plurality of execution paths in said sequence prior to said execution transfer inεtruction, and wherein εaid εtep of inspecting includes inεpecting inεtructionε in reverεe order backwardε through each of εaid execution pathε to determine a plurality of values for said destination addreεε including a value for said destination addresε obtained by inspecting instructionε in reverεe order of εaid execution εequence through each of εaid pathε. 20. The method as claimed in claim 19, wherein at least one of said execution pathε loopε back onto itεelf, and wherein εaid inεpecting inεtructionε in reverse order backwards through each of said execution paths includes the step of checking whether said each of εaid execution paths loop back onto itself, and terminating the inεpecting of instructions in said each of said execution paths when said each of said execution paths loop back onto itself. 21. The method aε claimed in claim 19, further comprising the stepε of: grouping consecutive ones of said instructionε into blockε, wherein the inεtructions in each block are executed in program address sequence and said execution transfer pathε occur from a last instruction in one of said blocks to a first inεtruction in one of said blockε; and generating for each block a SUBSTITUTE SHEET list of predeceεsor blocks from which execution transfer paths to said each block originate, and a list of εucceεsor blocks to which execution tranεfer paths from said each block extend; and wherein said step of inspecting instructions in reverse order backwards through each of said execution paths includes inεpecting instructions in reverse order backwards through the block including the execution transfer inεtruction and through lineε of predeceεεor blockε beginning with the predecessorε of εaid block including the execution transfer instruction. 22. The method aε claimed in claim 21, wherein each of εaid blockε haε an epoch number attribute, and wherein said search for at least one value of said destination addresε iε assigned an epoch number, and wherein each block is searched no more than once for a value for said deεtination address by setting the epoch number attribute of said each block equal to the epoch number when the block is searched, and detecting an attempt to search said each block a second time by comparing the epoch number to the epoch number attribute of the block. 23. The method as claimed in claim 19, wherein said computer program includes a sequence of instructions beginning at a destination addresε found for said execution transfer instruction, said sequence of instructionε beginning at εaid deεtination addreεε found for said execution transfer instruction defines an execution transfer path that loops back to an inεtruction in said program preceding εaid execution transfer inεtruction in εaid execution εequence, and wherein εaid method further compriεeε the εtep of decoding said sequence of inεtructionε beginning at εaid deεtination address of said execution transfer inεtruction to find said execution transfer path to said instruction in εaid program preceding said execution transfer inεtruction in said execution sequence, and thereupon again searching for a value of εaid destination address of said execution transfer instruction by inspecting, in reverse order of εaid execution εequence, decoded inεtructionε which precede in εaid execution sequence said execution tranεfer path that loops back. 24. A method of operating a digital computer to search for instructionε in an original computer program and to tranεlate the inεtructionε that are found to generate a tranεlated program; each of εaid inεtructionε having a reεpective program addreεε in εaid computer program; εaid computer program including inεtructionε SUBSTITUTE SHEET that transfer execution to specified addresεeε and that together with the program addreεses of said instructions define an execution sequence for said instructions, said execution sequence beginning at an entry point addresε in εaid program; εaid inεtructionε alεo including instructionε that εpecify operations that modify contents of memory at specified memory addresεes, and instructionε that εpecify operations that modify contents of specified general purpose registerε, εaid program including at leaεt one execution tranεfer inεtruction specifying a transfer of program execution to a destination addresε in said program determined from contents of a specified one of said general purpose registerε; εaid method compriεing the εtepε of: (a) decoding inεtructionε beginning at said entry point addresε, and when decoding εaid inεtructionε, recognizing that εaid execution tranεfer inεtruction haε a destination addreεε determined by the contentε of a εpecified one of εaid general purpoεe registers, and thereupon performing a search for at leaεt one value of εaid deεtination addreεs, said εearch including (1) forming an expreεεion of εaid deεtination addreεε in termε of the contentε that a deεignated one of εaid general purpose registerε will have during program execution, (2) inεpecting, in reverεe order of εaid execution sequence, instructionε in εaid execution εequence that precede said execution transfer instruction, and (i) when an inspected instruction specifieε modification of the contentε of a general purpoεe regiεter designated in said expreεεion but doeε not εpecify a modification εuch that εaid expreεεion expreεεeε a value that iε definite with reεpect to the addreεε of εaid inspected instruction, modifying said expresεion to account for the εpecified modification εo that εaid expression expresεeε εaid destination addresε in termε of contentε that at leaεt one designated general purpose register will have during program execution when program execution reaches the program addresε of the inεpected inεtruction, and (ii) when an inεpected inεtruction εpecifies modification of the contents of a general purpose regiεter designated in said expression such that said expression expresseε a value that iε definite with respect to the address of said inspected instruction, determining said value for said destination addresε from εaid expreεεion, (b) decoding inεtructionε beginning at the destination addresε found for the execution tranεfer inεtruction, and (c) translating the decoded instructions to generate said translated program. 25. The method as claimed in claim 24, wherein said expresεion includeε a memory access function expressing said destination address in terms of the contents of memory at a memory addresε specified by a memory access argument expression, and wherein said method further includes the step of attempting to match the memory access argument expression to a memory addresε εpecifier in the inεpected inεtruction when the inspected instruction modifies the contents of memory at a specified memory address, and when a match occurs, replacing the memory access function in said expreεεion with an expreεεion of the modified contentε of memory at the εpecified memory addreεε. » 26. The method aε claimed in claim 25, wherein εaid step of attempting to match the memory access argument of said expression to a memory addresε εpecifier in the inspected instruction includes searching instructions preceding said inspected inεtruction to find an inεtruction that εetε εaid memory address specifier to a form of expresεion matching εaid memory acceεs argument expresεion. 27. The method aε claimed in claim 24, further compriεing the εtep of attempting to match said expression to a predefined expression format for a subroutine argument pasεed to a εubroutine during a subroutine call operation, and when a match occurs, recording that a callback may occur to said subroutine parameter from said execution transfer instruction. 28. The method as claimed in claim 24, further comprising the step of attempting to match said expresεion to a predefined expression format for a subroutine argument of a subroutine call instruction when the address of the inspected instruction iε a deεtination address of a subroutine call instruction, and when a match is found, continuing said search by inspecting, in reverse order of said execution sequence, instructionε in said execution sequence that precede εaid subroutine call instruction. 29. The method as claimed in claim 24, wherein said execution sequence includes a plurality of execution pathε in εaid εequence prior to εaid execution tranεfer inεtruction, and wherein εaid step of inspecting includes inspecting instructionε in reverse order backwards through each of said execution paths to determine a plurality of values for said destination addresε including a value for said destination addreεε obtained by inspecting instructionε in reverεe order of said execution sequence through each of said paths. 30. The method as claimed in claim 29, wherein at least one of said execution paths loops back onto itself, and wherein said inspecting instructionε in reverεe order backwardε through each of εaid execution paths includes the step of checking whether said each of said execution paths loop back onto itself, and terminating the inspecting of instructionε in said each of said execution paths when said each of said execution paths loop back onto itself. . 31. The method as claimed in claim 19, further comprising the steps of: grouping consecutive ones of εaid instructions into blockε, wherein the inεtructionε in each block are executed in program address sequence and said execution transfer paths occur from a last instruction in one of said blocks to a first instruction SUBSTITUTE SHEET in one of said blocks; and generating for each block a list of predecessor blocks from which execution transfer paths to said each block originate, and a list of successor blockε to which execution transfer paths from said each block extend; and wherein said step of inspecting instructionε in reverse order backwards through each of said execution paths includes inspecting instructions in reverse order backwards through the block including the execution transfer inεtruction and through lines of predecessor blocks beginning with the predecesεorε of the block including the execution tranεfer inεtruction. 32. The method aε claimed in claim 19, wherein εaid computer program includeε a εequence of inεtructionε beginning at εaid deεtination addreεε found for the execution tranεfer inεtruction, εaid εequence of inεtructionε define an execution tranεfer path that loopε back to an inεtruction in said program preceding said execution transfer instruction in said execution εequence, and wherein εaid decoding of instructions beginning at said destination address of said execution transfer instruction finds said execution transfer path to said instruction in said program preceding said execution transfer inεtruction in εaid execution εequence, and thereupon initiateε a εearch for another value of said destination address of said execution transfer inεtruction by inspecting, in reverse order of said execution sequence, decoded instructions which precede in said execution sequence said execution transfer path that loopε back. 33. A digital computer εyεte for εearching for instructions in an original computer program and translating the instructionε that are found to generate a tranεlated program; each of said instructionε having a respective program addreεε in εaid computer program; said computer program including instructions that transfer execution to specified addresseε and that together with the program addreεεeε of εaid inεtructions define an execution sequence for said instructionε, εaid execution εequence beginning at an entry point addreεε in εaid program; said inεtructionε also including instructionε that specify operations that modify contents of memory at specified memory addresεeε, and inεtructions that specify operations that modify contents of specified general purpose registers, said program including at least one execution tranεfer inεtruction εpecifying a tranεfer of program execution to a deεtination addreεε in εaid program determined from contentε of a εpecified one of εaid general purpoεe regiεterε; εaid digital computer εyεtem comprising, in combination: (a) means for decoding instructions beginning at said entry point address, and when decoding said inεtructionε, recognizing that εaid execution tranεfer inεtruction has a destination address determined by the contents of a εpecified one of εaid general purpoεe regiεterε, and thereupon performing a εearch for at leaεt one value of said destination address, said search including (1) forming an expresεion of said destination address in terms of the contents that a designated one of said general purpose regiεters will have during program execution, (2) inεpecting, in reverεe order of εaid execution εequence, instructions in said execution sequence that precede said execution transfer instruction, and (i) when an inspected instruction specifieε modification of the contents of a general purpose register designated in said expresεion but doeε not εpecify a modification εuch that εaid expression expresεeε a value that iε definite with respect to the address of said inspected instruction, modifying said expreεεion to account for the specified modification so that said expression expresεeε said destination address in terms of contents that at least one general purpoεe register designated in said expression will have during program execution when program execution reaches the program addresε of the inεpected inεtruction, and (ii) when an inspected instruction specifies modification of the contents of a general purpose register designated in said expression such that said expresεion expreεεeε a value that iε definite with reεpect to the addreεε of εaid inspected instruction, determining εaid value for εaid deεtination addreεε from said expresεion; (b) meanε for decoding inεtructionε beginning at the deεtination addreεs found for the execution transfer instruction; and (c) means for translating the decoded inεtructionε to generate said tranεlated program. 34. The digital computer εystem as claimed in claim 33, wherein said means for decoding instructions beginning at said destination addresε found for εaid execution transfer instruction includes means for finding execution tranεfer pathε to inεtructions in said program preceding said execution transfer instruction in said execution sequence, and thereupon initiating searches for additional values of said destination addresε of εaid execution tranεfer instruction by inspecting, in reverse order of said execution εequence, decoded inεtructionε which precede in εaid execution εequence εaid execution tranεfer pathε to inεtructionε in εaid program preceding εaid execution tranεfer inεtruction in εaid εequence.

Inventors: SITES RICHARD L, SITES, RICHARD, L.
Applicants: DIGITAL EQUIPMENT CORP, DIGITAL EQUIPMENT CORPORATION
Application year: 1992
Main classification: G06F9
IPC codes: G06F9