⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 appendix b the salvm instruction set.htm

📁 英文版编译器设计:里面详细介绍啦C编译器的设计
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<P>The second step involves matching the result of the comparison to the 
particular instruction being executed. For instance, if we are executing a 
<TT>GTRx</TT> instruction, and the result was greater than zero, then we can 
return a true. If the result was equal to zero, or less than zero, then we would 
return a false. The result that is returned is pushed onto the stack as a byte 
containing a 1 for true and a zero for false.
<P>In these instructions, the EES ordering is the same as it has always been. In 
other words, if we want to compare A to B, then we push A onto the EES and then 
B. Let's have an example. See figure {COMPEX} <PRE>      dword B --&gt; |  257F9A01  |       4D8A2B09          |     01     |
      dword A --&gt; |  4D8A2B09  |     - 257F9A01          |            |
                  |            |      ----------         |            |
                  |    ...     |       280A9108          |    ...     |
                  |____________|                         |____________|
                       EES         Result is positive,        EES
                     Before              A &gt; B               After

      <B>Figure {COMPEX}</B>  A figure representing the comparison of two dwords
      to see if A is greater than or equal to B.
</PRE>As of yet, there are no instructions to compare tenbytes and and quad 
precision floats. These need to be done in blocks, starting with the most 
significant block, and comparing while equal until the last block, much like a 
string compare.
<P>
<H2>B.7 Flow Control Instructions</H2><!-------------------------------------------------------------------------------->The 
flow control op-codes deal with branching: either conditional or unconditional. 
The condidional jump instructions take one byte from the EES, and jump depending 
on whether the byte is zero or nonzero. Some of the jump op-codes take a 32-bit 
signed number designating the offset from the current PC to jump to. Table 
{JMPINS} explains these instructions. <PRE>        Op     Name                    Description                   New PC computed by
      ========================================================================================
        JMP    JuMP                    Unconditional jump            32-bit immediate offset
        SJMP   Short JuMP              Unconditional jump            16-bit immediate offset
        JMPS   Jump stack              Unconditional jump            New PC is on the EES

        JPZ    JumP if Zero            Jump if EES byte is zero      32-bit immediate offset
        JPNZ   JumP if NonZero         Jump if EES byte is nonzero   32-bit immediate offset
        SJPZ   Short JumP if Zero      Jump if EES byte is zero      16-bit immediate offset
        SJPNZ  Short JumP if NonZero   Jump if EES byte is nonzero   16-bit immediate offset

        JSR    Jump SubRoutine         Jump to subroutine            32-bit immediate offset
        JSRS   Jump SubRoutine stack   Jump to subroutine            New PC is on the EES
        RTS    ReTurn from Subroutine  Return from subroutine        dword stored at S

      <B>Table {JMPINS}</B>  the flow control instructions.
</PRE>For the most part, these instructions are straightforward. The first three 
branch unconditionally. <TT>JMPS</TT> jumps to a previously computed PC that is 
on the EES. Such a value would be computed using the <TT>LPCA</TT> instruction. 
The same goes for <TT>JSRS</TT>. The conditional jump instructions consume a 
byte from the EES, that is usually the previous result of a comparison.
<P>A subroutine is a little different from a jump. In fact, it is kind of half 
way between a jump and a procedure call. Upon executing a <TT>JSR</TT> or a 
<TT>JSRS</TT> instruction, the current PC is placed on the stack at S, and S is 
incremented by four bytes. Upon encountering a <TT>RTN</TT> instruction, the VM 
will decrement S by four, and retrieve the old PC. With subroutines, local 
variables are kept in scope, and a call to a subroutine is faster. In the SAL 
compiler, subroutines are used to perform cleanup of local variables prior to 
exiting a function. <TT>JMPS</TT> and <TT>JSRS</TT> are used in the compiler for 
exception handeling. The conditional instructions are used in the branching and 
looping statements in the compiler. These op-codes are fully explained in the 
chapters where they apply.
<P>
<H2>B.8 Procedural Instructions</H2><!-------------------------------------------------------------------------------->The 
procedural instructions are explained in chapter {Procedures and functions}. We 
will only briefly cover these instructions here. They are listed in table 
{PROCINS}. <PRE>        Op     Name
      ===============================================
        CL     Call Local
        CX     Call eXternal
        CI     Call Immediate
        CF     Call Formal
        CV     Call Virtual
        RTN    ReTurN from function/procedure
        ENTR   ENTeR procedure
        ALLOC  ALLOCate stack space
        PCOP   Parameter COPy
        GM     Get M register
        GB     Get Base local area

      <B>Table {PROCINS}</B>  The procedure-related op-codes.
</PRE><B><TT>CL</TT>: Call Local.</B> This instruction calls a procedure within 
the current module. This instruction is used in the default calling mechanism, 
i.e., neither the calling procedure or the procedure being called are nested, 
and the procedure is within the current module, and so on.
<P><B><TT>CX</TT>: Call eXternal.</B> We use this op-code whenever we call a 
procedure that is in another module. Usually, calling an external procedure 
involves setting the M, G, F, and R registers. This differentiates <TT>CL</TT> 
from <TT>CX</TT>.
<P><B><TT>CI</TT>: Call Immediate.</B> <TT>CI</TT> is used when both the calling 
procedure and the procedure being called are nested within another procedure. 
This instruction involves maintining the local variables of the last local call, 
since nested procedures can see local variables of the parent procedure. Nested 
procedures are rather like high-level subroutines. All local variables of the 
parent procedure are visible, and the nested procedure can have local variables 
of its own.
<P><B><TT>CF</TT>: Call Formal.</B> This op-code is used whenever we have a 
pointer to a procedure. Procedures are usually called by specifying a procedure 
number if the new procedure is local, or a module number and a procedure number 
if the new procedure is external. With <TT>CF</TT>, we can call to a procedure 
and begin execution at a specific address.
<P><B><TT>CV</TT>: Call Virtual.</B> This instruction calls a virtual function 
for a class. It is explained in more detail in the chapter on virtual functions.
<P><B><TT>RTN</TT>: ReTurN.</B> Reguardless of the method used to call a 
procedure or function, the method to return is the same. This instruction 
returns to the previous point of execution.
<P><B><TT>ENTR</TT>: ENTeR.</B> This is the first instruction of all procedures 
and functions. Its purpose is to reserve space on the stack for all local 
variables. Its presence is manditory, as all calling instructions check for it 
before continuing. If this instruction is not present, all of the <TT>Cx</TT> 
instructions will fail, causing a native exception.
<P><B><TT>ALLOC</TT>: ALLOCate.</B> This instruction's purpose is to allocate 
additional stack space for local copies of arrays, etc. 
<P>
<H2>B.9 Mischellaneous Instructions</H2><!-------------------------------------------------------------------------------->The 
last group of instructions is a really mixed bag. They do all sorts of things, 
and they are spread throughout the instruction space. They are listed in table 
{MISCINS}. <PRE>        Op     Name
      =========================================================
        TRON   TRace On
        TROFF  TRace OFF
        TRAP   TRAP
        DCAS   
        TS     Test and Set
        TR     Teas and Reset
        COPT   COPy Top
        POP    POP
        SWAP   SWAP
        RSYS   Register SYStem call
        SYS    SYStem call
        INCS   INCrement S
        DECS   DECrement S
        ASUB   Array SUBtract
        AINDX  Array INDeX
        NOP    NO Operation

      <B>Table {MISCINS}</B>  All the rest of the VM op-codes.
</PRE><B><TT>TRON</TT>: TRace On.</B> This instruction puts the VM into debug 
mode. The VM's software interface allows the programmer to set a native level 
callback, which gets passed the current state of the VM. Using this feature, VM 
developers can write an integrated debugger for the VM. In debug mode, the VM 
will make a call to the callback after executing each instruction.
<P><B><TT>TROFF</TT>: TRace OFF.</B> This has the opposite effect of 
<TT>TRON</TT>. If the VM is in debug mode, it will leave debug mode. Otherwise 
it will have no effect.
<P><B><TT>TRAP</TT>: TRAP.</B> This instruction throws a native exception 
signalling some fatal error within the VM. VM developers may also choose to set 
a callback function to handle these errors. They are always fatal, and upon 
returning from the callback, the VM will exit. The fatal errors of the VM are 
listed in table {VMERRS} <PRE>        Error Name           Error Description
      ========================================================================
        TRAP_NOERROR,        No error has occurred
        TRAP_INVALIDPROC,    Tried to call an invalid procedure
        TRAP_INVALIDOP,      Tried to execute an invalid op-code
        TRAP_INVALIDOPERAND, An operand was invalid for a particular op-code
        TRAP_INVALIDSYS,     Attempt to call some non-existant syscall
        TRAP_ARRAYRANGE,     Array subscript error
        TRAP_EESUNDER,       EES underflow
        TRAP_EESOVER,        EES overflow
        TRAP_NOMALLOC,       Unable to allocate memory
        TRAP_INVALIDMOD,     Reference to an invalid module
        TRAP_STACKUNDER,     Procedure stack underflow 
        TRAP_STACKOVER,      Procedure stack overflow
        TRAP_LSNULL,         Tried to use LSx with a null pointer in EES
        TRAP_INVALIDSUBFUNC, Attempt to call some non-existant syscall sub-function
        TRAP_EXUNHANDLED,    An unhandled SAL Exception was encountered
        TRAP_EXCORRUPT,      Exception stack not empty, or corrupt
        TRAP_EXCEPTION       An unknown SAL exception was thrown

      <B>Table {VMERRS}</B>  A listing of the fatal VM errors.  These are typedefed in
      an enumerated type, called EnumTrap.
</PRE><B><TT>DCAS</TT>: .</B> Double Compare And Swap.
<P>This instruction takes from the EES two addresses and 4 U32 values. If the 
both values at the Addresses are equal to the first pair of U32 parameters, the 
value at both addresses is set to the second pair of U32 values. <B><TT>TS</TT>: 
Test and Set.</B> This instruction will test a byte at a given address found on 
the EES. The byte will be set to true, and the previous value at that address 
will be pushed onto the EES
<P><B><TT>TR</TT>: Test and Reset.</B> This instruction does a similar thing, 
but it will set a byte to zero, instead. <TT>TS</TT> and <TT>TR</TT> are used to 
design synchronization primitives. They are useful for making semaphores and 
critical sections.
<P><B><TT>COPT</TT>: COPy Top.</B> This instruction will make a copy of the 
topmost <I>n</I> bytes on the EES. The amount of bytes copies is a one-byte 
immediate parameter, and must have the values 1, 2, 4, or 8. This instruction is 
most useful for copying a pointer at the top of the EES.
<P><B><TT>POP</TT>: POP.</B> This op-code takes a two-byte immediate parameter, 
designating the amount of bytes of the EES to be discarded.
<P><B><TT>SWAP</TT>: SWAP.</B> This instruction takes two word-sized immediate 
parameters, <I>m</I> and <I>n</I>. It's function is to swap the topmost <I>m</I> 
bytes of the EES with the <I>n</I> bytes underneath.
<P>This instruction is handy when working with stack-based architectures. Often, 
a pointer will be buried at the bottom of the EES, and will need to be brought 
to the top. Other times, data will get pushed onto the EES in the wrong order.
<P><B><TT>RSYS</TT>: Register SYStem call.</B> This procedure registers a SAL 
function as a system call. (not yet defined how this will work)
<P><B><TT>SYS</TT>: SYStem call.</B> This op-code will invoke a native-level 
service of some sort. Virtual machines by their nature are rather slow, and 
often- repeated tasks, like converting data to text or moving blocks of memory 
can be really slow, if done by the VM directly. The SYS calls are analogous to 
the software interrupts in the Intel x86 architecture under DOS, except they are 
more numerous, and include the functionality of the standard C library. They 
perform math, string manipulation, file I/O, console input and output, network 
communication, and a host of other services. This is how SAL programs can 
interface with the rest of the computer.
<P><B><TT>INCS</TT>: INCrement S.</B> This instruction increments the S 
register, effectively allocating more space within the local call frame. It 
takes an immediate dword parameter.
<P><B><TT>DECS</TT>: DECrement S.</B> This op-code decrements the S register by 
the value specified in an immediate dword parameter. The <TT>INCS</TT> and 
<TT>DECS</TT> instructions are used for reserving stack space for functions that 
return complex data by value, like an array or a record.
<P><B><TT>ASUB</TT>: Array SUBtract.</B> This and the <TT>AINDX</TT> 
instructions are explained more in {Chapter on arrays and records}. 
<TT>AINDX</TT> will take a dword on the EES, and test to see if it is within the 
lower boundary of an array subscript. If so, it will subrtact the value by the 
array's lower boundary. If not, it will throw a native exception.
<P><B><TT>AINDX</TT>: Array INDeX.</B> This instruction will take a zero-based 
array index (a 32-bit value on the EES) and test it to see if it is within the 
arrays upper limit. If it is, it will multiply the index by the size of one 
element of the array, and add it to the current base address (also on the EES).
<P><B><TT>NOP</TT>: No Operation.</B> <TT>NOP</TT>'s job is to do nothing. It is 
useful for word-aligning instructions, or for just filling in gaps in the code- 
stream. Its presence in the instruction set is traditional, and it is not used 
in the compiler.
<P><!-------------------------------------------------------------------------------->
<P>
<P></P></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -