JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用

JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用
    在完成了 这里和 这里的工作之后,就可以写程序生成机器码了。在生成机器码的时候有如下注意事项:

    1:可执行代码所在的空间必须使用VirtualAlloc与PAGE_EXECUTE_READWRITE标记分配。
    2:程序需要的常量空间、全局变量空间和指令空间需要分开在三个不同的地方。

    下面的例子使用一个struct保存指令的每一个部分,并且结合之前产生的指令译码表生成二进制码。

  1  #include  " ..\..\..\..\VL++\Library\Platform\VL_Console.h "
  2  #include  " ..\..\..\..\VL++\Library\Script\JIT\Assembler\VL_JIT_X86Generator.h "
  3  #include  < windows.h >
  4 
  5  using   namespace  vl;
  6  using   namespace  vl::platform;
  7  using   namespace  vl::jit::x86;
  8  using   namespace  vl::jit::assembly;
  9 
 10  extern   void  Main_Generator();
 11 
 12  #define  GET_LABEL(NAME,VARIABLE)                                \
 13      {                                                            \
 14          VARIABLE = Program.LabelNames.IndexOf(L#NAME);            \
 15           if (VARIABLE ==- 1 )                                        \
 16          {                                                        \
 17              VARIABLE = Program.LabelNames.GetCount();                \
 18              Program.LabelNames.Add(L#NAME);                        \
 19              Program.Labels.Add( - 1 );                                \
 20          }                                                        \
 21      }
 22 
 23  #define  INSTRUCTION(NAME)                                        \
 24      {                                                            \
 25          VL_AsmIns Ins;                                            \
 26          Ins.Name = L#NAME;                                        \
 27          Ins.ParameterCount = 0 ;                                    \
 28          Program.Instructions.Add(Ins);                            \
 29      }
 30  #define  LABEL(NAME)                                                \
 31      {                                                            \
 32          VInt LabelIndex = 0 ;                                        \
 33          GET_LABEL(NAME,LabelIndex);                                \
 34          VInt InsIndex = Program.Instructions.GetCount();            \
 35          Program.Labels[LabelIndex] = InsIndex;                    \
 36      }
 37  #define  PARAM_IMM_32(IMMEDIATE)                                    \
 38      {                                                            \
 39          VInt Index = Program.Instructions.GetCount() - 1 ;            \
 40          VL_AsmIns &  Ins = Program.Instructions[Index];                \
 41          VInt PRMIDX = Ins.ParameterCount ++ ;                        \
 42          Ins.Parameters[PRMIDX].ParameterKind = vapkSigned;        \
 43          Ins.Parameters[PRMIDX].ParameterType = vaptInt32;            \
 44          Ins.Parameters[PRMIDX].Signed = IMMEDIATE;                \
 45      }
 46  #define  PARAM_REG_32(REGISTER)                                    \
 47      {                                                            \
 48          VInt Index = Program.Instructions.GetCount() - 1 ;            \
 49          VL_AsmIns &  Ins = Program.Instructions[Index];                \
 50          VInt PRMIDX = Ins.ParameterCount ++ ;                        \
 51          Ins.Parameters[PRMIDX].ParameterKind = vapkRegister;        \
 52          Ins.Parameters[PRMIDX].ParameterType = vaptInt32;            \
 53          Ins.Parameters[PRMIDX].Register = var##REGISTER;            \
 54      }
 55  #define  PARAM_MI_32(INDEX,SCALE,BASE,OFFSET)                    \
 56      {                                                            \
 57          VInt Index = Program.Instructions.GetCount() - 1 ;            \
 58          VL_AsmIns &  Ins = Program.Instructions[Index];                \
 59          VInt PRMIDX = Ins.ParameterCount ++ ;                        \
 60          Ins.Parameters[PRMIDX].ParameterKind = vapkPointer;        \
 61          Ins.Parameters[PRMIDX].ParameterType = vaptInt32;            \
 62          Ins.Parameters[PRMIDX].Base = var##BASE;                    \
 63          Ins.Parameters[PRMIDX].Index = var##INDEX;                \
 64          Ins.Parameters[PRMIDX].Scale = vas##SCALE;                \
 65          Ins.Parameters[PRMIDX].Offset = OFFSET;                    \
 66      }
 67  #define  PARAM_LABEL(NAME)                                        \
 68      {                                                            \
 69          VInt Index = Program.Instructions.GetCount() - 1 ;            \
 70          VInt Label = 0 ;                                            \
 71          GET_LABEL(NAME,Label);                                    \
 72          VL_AsmIns &  Ins = Program.Instructions[Index];                \
 73          VInt PRMIDX = Ins.ParameterCount ++ ;                        \
 74          Ins.Parameters[PRMIDX].ParameterKind = vapkLabel;            \
 75          Ins.Parameters[PRMIDX].ParameterType = vaptInt32;            \
 76          Ins.Parameters[PRMIDX].Label = Label;                        \
 77      }
 78 
 79  VL_AsmCompiled *  Compile()
 80  {
 81      VL_AsmProgram Program;
 82      {
 83           //  XOR EAX, EAX
 84          INSTRUCTION(XOR)
 85          PARAM_REG_32(EAX)
 86          PARAM_REG_32(EAX)
 87           //  MOV ECX, [EDI]
 88          INSTRUCTION(MOV)
 89          PARAM_REG_32(ECX)
 90          PARAM_MI_32(NONE, 1 ,EDI, 0 )
 91           //  @BEGIN:
 92          LABEL(BEGIN)
 93               //  CMP ECX, 0
 94              INSTRUCTION(CMP)
 95              PARAM_REG_32(ECX)
 96              PARAM_IMM_32( 0 )
 97               //  JE @END
 98              INSTRUCTION(JE)
 99              PARAM_LABEL(END)
100               //  ADD EAX, [ECX * 4 + EDI]
101              INSTRUCTION(ADD)
102              PARAM_REG_32(EAX)
103              PARAM_MI_32(ECX, 4 ,EDI, 0 )
104               //  SUB ECX, 1
105              INSTRUCTION(SUB)
106              PARAM_REG_32(ECX)
107              PARAM_IMM_32( 1 )
108               //  JMP @BEGIN
109              INSTRUCTION(JMP)
110              PARAM_LABEL(BEGIN)
111           //  @END:
112          LABEL(END)
113           //  RET
114          INSTRUCTION(RET)
115      }
116      VL_AsmCompiled *  Compiled = Compile( & Program);
117       if (Compiled -> Errors.GetCount())
118      {
119           for (VInt i = 0 ;i < Compiled -> Errors.GetCount();i ++ )
120          {
121              VL_AsmError &  Error = Compiled -> Errors[i];
122              GetConsole() -> Write(L " [ " + VUnicodeString(Error.Index) + L " ] " + Error.Message + L " \r\n " );
123          }
124          delete Compiled;
125           return   0 ;
126      }
127       else
128      {
129           return  Compiled;
130      }
131  }
132 
133  void  vlmain()
134  {
135      GetConsole() -> SetTitle(L " Vczh Library++ 2.0 Assembler " );
136      GetConsole() -> SetTestMemoryLeaks( true );
137      GetConsole() -> SetPauseOnExit( true );
138 
139      VL_AsmCompiled *  Compiled = Compile();
140       if (Compiled)
141      {
142          VInt Size = (VInt)Compiled -> InstructionBuffer.Size();
143           void *  Buffer = VirtualAlloc( 0 ,Size,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
144          Compiled -> InstructionBuffer.SeekFromBegin( 0 );
145          Compiled -> InstructionBuffer.Read(Buffer,Size);
146 
147          VInt Params[] = { 10 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };
148          VInt *  Input = Params;
149          VInt Output = 0 ;
150          __asm
151          {
152              PUSH EAX
153              PUSH EBX
154              PUSH ECX
155              PUSH EDX
156              PUSH ESI
157              PUSH EDI
158              MOV EAX, dword ptr[Buffer]
159              MOV EDI, dword ptr[Input]
160              INT  3
161              CALL EAX
162              MOV dword ptr[Output], EAX
163              POP EDI
164              POP ESI
165              POP EDX
166              POP ECX
167              POP EBX
168              POP EAX
169          }
170          VirtualFree(Buffer,Size,MEM_RELEASE);
171          GetConsole() -> Write(L " 结果:EAX= " + VUnicodeString(Output) + L " \r\n " );
172          delete Compiled;
173      }
174  }

    注意,VL_AsmCompiled* Compile()函数使用的宏用于简化汇编的编码(以后将写一个分析器将字符串的汇编转换成这些struct)。EDI指向11个32位整数(见下文对vlmain函数的说明)。程序首先将EDI[0]存放在ECX,此时ECX是10。然后执行一个循环让EAX=EDI[10]+EDI[9]+...+EDI[2]+EDI[1],然后ECX变成0,退出。

    vlmain函数中的汇编首先将存放着指令的Buffer放入EAX,然后将Params数组的指针放入EDI,然后执行函数(INT 3用于在Visual Studio中产生断点)。汇编将结果保存在了EAX中,因此将EAX的结果村放入Output变量。最后输出。

    下面是两张调试的贴图。使用Visual Studio的反汇编功能可以检查汇编器是否正确:

    首先,程序运行到INT 3的时候会产生调试中断,这个时候使用Visual Studio捕获:
JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用_第1张图片

    按CTRL+ALT+D进入汇编窗口以便跟踪(代码窗口不能单步进CALL):
JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用_第2张图片

    执行到CALL EAX的时候按F11进入我们写程序生成的代码:
JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用_第3张图片

    这里我们可以看到,程序产生的结果是正确的。于是CPU将顺利执行这段代码,最后将EAX变为55:
JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用_第4张图片

    到这里就结束了。以下是汇编器的源代码的核心部分。首先是结构的声明:
  1  /* ******************************************************************************
  2  Vczh Library++ 2.0
  3  JIT::x86汇编数据结构
  4  开发者:陈梓瀚
  5 
  6  接口:
  7  类:
  8  函数:
  9  ****************************************************************************** */
 10  #ifndef VL_JIT_ASSEMBLY
 11  #define  VL_JIT_ASSEMBLY
 12 
 13  #include  " ..\..\..\Data\Data\VL_Data_Basic.h "
 14  #include  " ..\..\..\Data\Data\VL_Data_String.h "
 15  #include  " ..\..\..\Data\Data\VL_Data_List.h "
 16  #include  " ..\..\..\Data\Data\VL_Data_Map.h "
 17  #include  " ..\..\..\Data\VL_Stream.h "
 18 
 19  namespace  vl
 20  {
 21       namespace  jit
 22      {
 23           namespace  assembly
 24          {
 25               using   namespace  collection;
 26               using   namespace  stream;
 27 
 28               enum  VLE_AsmParameterKind
 29              {
 30                  vapkRegister,             /* 寄存器 */
 31                  vapkPointer,             /* 指针 */
 32                  vapkSigned,                 /* 有符号数字 */
 33                  vapkUnsigned,             /* 无符号数字 */
 34                  vapkRelative,             /* 相对指针 */
 35                  vapkLabel                 /* Label指定的Relative指针常数 */
 36              };
 37 
 38               enum  VLE_AsmParameterType
 39              {
 40                  vaptInt8,
 41                  vaptInt16,
 42                  vaptInt32,
 43                  vaptFp32,
 44                  vaptFp64,
 45                  vaptFpReg
 46              };
 47 
 48               /* 分段保持顺序 */
 49               enum  VLE_AsmRegister
 50              {
 51                  varAL,
 52                  varAH,
 53                  varBL,
 54                  varBH,
 55                  varCL,
 56                  varCH,
 57                  varDL,
 58                  varDH,
 59 
 60                  varAX,
 61                  varBX,
 62                  varCX,
 63                  varDX,
 64                  varSP,
 65                  varBP,
 66                  varSI,
 67                  varDI,
 68 
 69                  varEAX,
 70                  varEBX,
 71                  varECX,
 72                  varEDX,
 73                  varESP,
 74                  varEBP,
 75                  varESI,
 76                  varEDI,
 77 
 78                  varST0,
 79                  varST1,
 80                  varST2,
 81                  varST3,
 82                  varST4,
 83                  varST5,
 84                  varST6,
 85                  varST7,
 86 
 87                  varNONE
 88              };
 89 
 90               /* 保持顺序 */
 91               enum  VLE_AsmScale
 92              {
 93                  vas1,
 94                  vas2,
 95                  vas4,
 96                  vas8
 97              };
 98 
 99               enum  VLE_AsmErrorCode
100              {
101                  vaecUnrecognizedName,                         /* 不能识别的指令名称 */
102                  vaecWrongParameterCount,                     /* 错误的参数数量 */
103                  vaecUnrecognizedKind,                         /* 不能识别的参数样式 */
104                  vaecUnrecognizedType,                         /* 不能识别的参数类型 */
105 
106                  vaecLostRegister,                             /* 寄存器为NONE */
107                  vaecWrongRegisterType,                         /* 寄存器与参数值类型不匹配 */
108                  vaecUnrecognizedRegister,                     /* 无法识别的寄存器值 */
109 
110                  vaecLabelMustBeInt32,                         /* Label的类型必须是32位整数 */
111                  vaecUnrecognizedLabel,                         /* 无法识别的Label值 */
112 
113                  vaecIndexRegisterMustBe32Bits,                 /* Index寄存器必须是32位 */
114                  vaecBaseRegisterMustBe32Bits,                 /* Base寄存器必须是32位 */
115                  vaecUnrecognizedScale,                         /* 无法识别的Scale值 */
116 
117                  vaecSignedMustBeInteger,                     /* 有符号整数的类型必须是整数 */
118                  vaecUnsignedMustBeInteger,                     /* 无符号整数的类型必须是整数 */
119                  vaecRelativeMustBeInteger,                     /* 相对地址必须是整数类型 */
120                  vaecSignedOutOfRange,                         /* 有符号整数超过类型描述的范围 */
121                  vaecUnsignedOutOfRange,                         /* 无符号整数超过类型描述的范围 */
122 
123                  vaecUnrecognizedLinkingID,                     /* 【】无法识别的链接ID */
124                  vaecParameterNotMatched,                     /* 参数无法匹配指令的要求 */
125                  vaecDoNotKnowHowToCompile                     /* 不知道如何编译 */
126              };
127 
128               struct  VL_AsmError
129              {
130                  VLE_AsmErrorCode        ErrorCode;
131                  VInt                    Index;
132                  VUnicodeString            Message;
133              };
134 
135               struct  VL_AsmParameter
136              {
137                  VLE_AsmParameterKind    ParameterKind;         /* 参数样式,决定Union哪些可用 */
138                  VLE_AsmParameterType    ParameterType;         /* 参数数值类型 */
139                   struct
140                  {
141                      VInt                LinkingID;             /* 链接数值ID */
142                      VInt                LinkingOffset;         /* 链接数值偏移 */
143                      VBool                Enabled;             /* 是否允许链接,参数类型不接受链接则忽略 */
144                  }                        Linking;
145                  union
146                  {
147                      VInt32s                Signed;                 /* vapkSigned、vapkRelative有效,Linking.Enable为true则使用Linking */
148                      VInt32u                Unsigned;             /* vapkUnsigned有效,Linking.Enable为true则使用Linking */
149                      VInt                Label;                 /* vapkLabel有效 */
150                      VLE_AsmRegister        Register;             /* 寄存器 */
151                       struct
152                      {
153                          VLE_AsmRegister    Index;                 /* 底数寄存器,为varNONE则忽略Index*Scale */
154                          VLE_AsmScale    Scale;                 /* 指数 */
155                          VLE_AsmRegister    Base;                 /* 偏移寄存器,为varNONE则忽略Base */
156                          VInt            Offset;                 /* 常数偏移,Linking.Enable为true则使用Linking */
157                      };
158                  };
159 
160                  VL_AsmParameter();
161              };
162 
163               struct  VL_AsmIns
164              {
165                  VUnicodeString            Name;                 /* 指令名字 */
166                  VInt                    ParameterCount;         /* 有效参数数量 */
167                  VL_AsmParameter            Parameters[ 4 ];         /* 参数 */
168              };
169 
170               struct  VL_AsmProgram
171              {
172                  typedef VL_List < VInt ,  true >                     _LabelMap;
173                  typedef VL_List < VL_AsmIns ,  false >                 _InsList;
174                  typedef VL_List < VUnicodeString ,  false >             _LabelList;
175 
176                   static   const  VInt        CONSTANT_BUFFER_POINTER = 0 ;         /* LinkingID:常数缓冲区指针 */
177 
178                  VL_MemoryStream            ConstantBuffer;         /* 常数缓冲区 */
179                  _LabelMap                Labels;                 /* ID -> Instruction */
180                  _InsList                Instructions;         /* 指令表 */
181                  _LabelList                LabelNames;             /* ID -> Name */
182 
183                  VL_AsmProgram();
184              };
185 
186               struct  VL_AsmCompiled
187              {
188                  typedef VL_List < VL_AsmError ,  false >             _ErrorList;
189 
190                  _ErrorList                Errors;
191                  VL_MemoryStream            ConstantBuffer;
192                  VL_MemoryStream            InstructionBuffer;
193                  VL_MemoryStream            LinkingBuffer;
194 
195                  VL_AsmCompiled();
196              };
197          }
198      }
199  }
200 
201  #endif

    其次是产生二进制码的程序:
  1  #include  " VL_JIT_X86Generator.h "
  2  #include  " VL_JIT_X86.h "
  3 
  4  namespace  vl
  5  {
  6       namespace  jit
  7      {
  8           namespace  x86
  9          {
 10               void  CopyStream(IVL_Stream *  In , IVL_Stream *  Out)
 11              {
 12                  VByte Buffer[ 65536 ];
 13                  VInt Count = 0 ;
 14                  In -> SeekFromBegin( 0 );
 15                  Out -> SeekFromBegin( 0 );
 16                   while (Count = In -> Read(Buffer, sizeof (Buffer)))
 17                  {
 18                      Out -> Write(Buffer,Count);
 19                  }
 20                  In -> SeekFromBegin( 0 );
 21                  Out -> SeekFromBegin( 0 );
 22              }
 23 
 24              VBool CheckParameter(VLE_InsParam Template , VL_AsmParameter &  Assembly)
 25              {
 26                   switch (Template)
 27                  {
 28                   case  vipREL_8:             return  Assembly.ParameterKind == vapkRelative  &&  Assembly.ParameterType == vaptInt8;
 29                   case  vipREL_16:             return  Assembly.ParameterKind == vapkRelative  &&  Assembly.ParameterType == vaptInt16;
 30                   case  vipREL_32:             return  (Assembly.ParameterKind == vapkRelative  &&  Assembly.ParameterType == vaptInt32)  ||  Assembly.ParameterKind == vapkLabel;
 31                   case  vipPTR_16_16:         return  Assembly.ParameterKind == vapkUnsigned  &&  Assembly.ParameterType == vaptInt32;
 32                   case  vipPTR_16_32:         return   false ;
 33                   case  vipREG_8:             return  Assembly.ParameterKind == vapkRegister  &&  Assembly.ParameterType == vaptInt8;
 34                   case  vipREG_16:             return  Assembly.ParameterKind == vapkRegister  &&  Assembly.ParameterType == vaptInt16;
 35                   case  vipREG_32:             return  Assembly.ParameterKind == vapkRegister  &&  Assembly.ParameterType == vaptInt32;
 36                   case  vipIMM_8:             return  (Assembly.ParameterKind == vapkSigned  ||  Assembly.ParameterKind == vapkUnsigned)  &&  Assembly.ParameterType == vaptInt8;
 37                   case  vipIMM_16:             return  (Assembly.ParameterKind == vapkSigned  ||  Assembly.ParameterKind == vapkUnsigned)  &&  Assembly.ParameterType == vaptInt16;
 38                   case  vipIMM_32:             return  (Assembly.ParameterKind == vapkSigned  ||  Assembly.ParameterKind == vapkUnsigned)  &&  Assembly.ParameterType == vaptInt32;
 39                   case  vipRM_8:             return  (Assembly.ParameterKind == vapkRegister  ||  Assembly.ParameterKind == vapkPointer)  &&  Assembly.ParameterType == vaptInt8;
 40                   case  vipRM_16:             return  (Assembly.ParameterKind == vapkRegister  ||  Assembly.ParameterKind == vapkPointer)  &&  Assembly.ParameterType == vaptInt16;
 41                   case  vipRM_32:             return  (Assembly.ParameterKind == vapkRegister  ||  Assembly.ParameterKind == vapkPointer)  &&  Assembly.ParameterType == vaptInt32;
 42                   case  vipM_16_16:         return   false ;
 43                   case  vipM_16_32:         return   false ;
 44                   case  vipM_16_AND_16:     return   false ;
 45                   case  vipM_16_AND_32:     return   false ;
 46                   case  vipM_32_AND_32:     return   false ;
 47                   case  vipMI_16:             return  Assembly.ParameterKind == vapkPointer  &&  Assembly.ParameterType == vaptInt16;
 48                   case  vipMI_32:             return  Assembly.ParameterKind == vapkPointer  &&  Assembly.ParameterType == vaptInt32;
 49                   case  vipMI_64:             return   false ;
 50                   case  vipMF_32:             return  Assembly.ParameterKind == vapkPointer  &&  Assembly.ParameterType == vaptFp32;
 51                   case  vipMF_64:             return  Assembly.ParameterKind == vapkPointer  &&  Assembly.ParameterType == vaptFp64;
 52                   case  vipMF_80:             return   false ;
 53                   case  vipSREG:             return   false ;
 54                   case  vipST_0:             return  Assembly.ParameterKind == vapkRegister  &&  Assembly.Register == varST0;
 55                   case  vipST_I:             return  Assembly.ParameterKind == vapkRegister  &&  (Assembly.Register >= varST0  &&  Assembly.Register <= varST7);
 56                   case  vipAL:                 return  Assembly.ParameterKind == vapkRegister  &&  Assembly.Register == varAL;
 57                   case  vipAX:                 return  Assembly.ParameterKind == vapkRegister  &&  Assembly.Register == varAX;
 58                   case  vipEAX:             return  Assembly.ParameterKind == vapkRegister  &&  Assembly.Register == varEAX;
 59                   case  vipCL:                 return  Assembly.ParameterKind == vapkRegister  &&  Assembly.Register == varCL;
 60                   case  vipCX:                 return  Assembly.ParameterKind == vapkRegister  &&  Assembly.Register == varCX;
 61                   case  vipECX:             return  Assembly.ParameterKind == vapkRegister  &&  Assembly.Register == varECX;
 62                   case  vipCS:                 return   false ;
 63                   case  vipDS:                 return   false ;
 64                   case  vipES:                 return   false ;
 65                   case  vipFS:                 return   false ;
 66                   case  vipGS:                 return   false ;
 67                   case  vipSS:                 return   false ;
 68                   case  vipCONST_1:         return  Assembly.ParameterKind == vapkUnsigned  &&  Assembly.Linking.Enabled == false   &&  Assembly.Unsigned == 1 ;
 69                   case  vipCONST_3:         return  Assembly.ParameterKind == vapkUnsigned  &&  Assembly.Linking.Enabled == false   &&  Assembly.Unsigned == 3 ;
 70                   default :                 return   false ;
 71                  }
 72              }
 73               /*
 74                  VInt Selected=-1;
 75                  for(VInt i=0;i<4;i++)
 76                  {
 77                      switch(Format.Params[i])
 78                      {
 79                      case vipREL_8:
 80                      case vipREL_16:
 81                      case vipREL_32:
 82                      case vipPTR_16_16:
 83                      case vipPTR_16_32:
 84                      case vipREG_8:
 85                      case vipREG_16:
 86                      case vipREG_32:
 87                      case vipIMM_8:
 88                      case vipIMM_16:
 89                      case vipIMM_32:
 90                      case vipRM_8:
 91                      case vipRM_16:
 92                      case vipRM_32:
 93                      case vipM_16_16:
 94                      case vipM_16_32:
 95                      case vipM_16_AND_16:
 96                      case vipM_16_AND_32:
 97                      case vipM_32_AND_32:
 98                      case vipMI_16:
 99                      case vipMI_32:
100                      case vipMI_64:
101                      case vipMF_32:
102                      case vipMF_64:
103                      case vipMF_80:
104                      case vipSREG:
105                      case vipST_0:
106                      case vipST_I:
107                      case vipAL:
108                      case vipAX:
109                      case vipEAX:
110                      case vipCL:
111                      case vipCX:
112                      case vipECX:
113                      case vipCS:
114                      case vipDS:
115                      case vipES:
116                      case vipFS:
117                      case vipGS:
118                      case vipSS:
119                      case vipCONST_1:
120                      case vipCONST_3:
121                          if(!Used[i])
122                          {
123                              Selected=i;
124                              Used[i]=true;
125                          }
126                      }
127                  }
128                  return Selected;
129               */
130 
131              VInt FindRI(VLS_InsFormat &  Format , VBool *  Used)
132              {
133                  VInt Selected =- 1 ;
134                   for (VInt i = 0 ;i < 4 ;i ++ )
135                  {
136                       switch (Format.Params[i])
137                      {
138                       case  vipREG_8:
139                       case  vipREG_16:
140                       case  vipREG_32:
141                       case  vipAL:
142                       case  vipAX:
143                       case  vipEAX:
144                       case  vipCL:
145                       case  vipCX:
146                       case  vipECX:
147                           if ( ! Used[i])
148                          {
149                              Selected = i;
150                              Used[i] = true ;
151                          }
152                      }
153                  }
154                   return  Selected;
155              }
156 
157              VInt FindRM(VLS_InsFormat &  Format , VBool *  Used)
158              {
159                  VInt Selected =- 1 ;
160                   for (VInt i = 0 ;i < 4 ;i ++ )
161                  {
162                       switch (Format.Params[i])
163                      {
164                       case  vipPTR_16_16:
165                       case  vipPTR_16_32:
166                       case  vipRM_8:
167                       case  vipRM_16:
168                       case  vipRM_32:
169                       case  vipM_16_16:
170                       case  vipM_16_32:
171                       case  vipM_16_AND_16:
172                       case  vipM_16_AND_32:
173                       case  vipM_32_AND_32:
174                       case  vipMI_16:
175                       case  vipMI_32:
176                       case  vipMI_64:
177                       case  vipMF_32:
178                       case  vipMF_64:
179                       case  vipMF_80:
180                           if ( ! Used[i])
181                          {
182                              Selected = i;
183                              Used[i] = true ;
184                          }
185                      }
186                  }
187                   return  Selected;
188              }
189 
190              VInt FindRF(VLS_InsFormat &  Format , VBool *  Used)
191              {
192                  VInt Selected =- 1 ;
193                   for (VInt i = 0 ;i < 4 ;i ++ )
194                  {
195                       switch (Format.Params[i])
196                      {
197                       case  vipST_I:
198                           if ( ! Used[i])
199                          {
200                              Selected = i;
201                              Used[i] = true ;
202                          }
203                      }
204                  }
205                   return  Selected;
206              }
207 
208              VInt FindIMM(VLS_InsFormat &  Format , VBool *  Used)
209              {
210                  VInt Selected =- 1 ;
211                   for (VInt i = 0 ;i < 4 ;i ++ )
212                  {
213                       switch (Format.Params[i])
214                      {
215                       case  vipREL_8:
216                       case  vipREL_16:
217                       case  vipREL_32:
218                       case  vipPTR_16_16:
219                       case  vipPTR_16_32:
220                       case  vipIMM_8:
221                       case  vipIMM_16:
222                       case  vipIMM_32:
223                           if ( ! Used[i])
224                          {
225                              Selected = i;
226                              Used[i] = true ;
227                          }
228                      }
229                  }
230                   return  Selected;
231              }
232 
233              VInt RegisterToExt(VLE_AsmRegister Register)
234              {
235                   switch (Register)
236                  {
237                   case  varAL: case  varAX: case  varEAX: case  varST0:
238                       return   0 ;
239                   case  varCL: case  varCX: case  varECX: case  varST1:
240                       return   1 ;
241                   case  varDL: case  varDX: case  varEDX: case  varST2:
242                       return   2 ;
243                   case  varBL: case  varBX: case  varEBX: case  varST3:
244                       return   3 ;
245                   case  varAH: case  varSP: case  varESP: case  varST4:
246                       return   4 ;
247                   case  varCH: case  varBP: case  varEBP: case  varST5:
248                       return   5 ;
249                   case  varDH: case  varSI: case  varESI: case  varST6:
250                       return   6 ;
251                   case  varBH: case  varDI: case  varEDI: case  varST7:
252                       return   7 ;
253                   default :
254                       return   - 1 ;
255                  }
256              }
257 
258              VByte RegisterToID(VLE_AsmRegister Register)
259              {
260                   return  (VByte)RegisterToExt(Register);
261              }
262 
263               const  VByte SIB_Scales[] = { 0 , 1 , 2 , 3 };
264              VByte ScaleToSIB(VLE_AsmScale Scale)
265              {
266                   return  SIB_Scales[Scale] << 6 ;
267              }
268 
269              VByte IndexToSIB(VLE_AsmRegister Register)
270              {
271                   return  (VByte)RegisterToExt(Register) << 3 ;
272              }
273 
274              VByte BaseToSIB(VLE_AsmRegister Register)
275              {
276                   return  (VByte)RegisterToExt(Register);
277              }
278 
279               // [Mod][Ext][R/M] [Scale][Index][Base]
280              VBool MakeModRMWithoutExt(VL_AsmParameter &  Parameter , VByte &  ModRM , VByte &  SIB , VBool &  EnableSIB , VBool &  Displayment)
281              {
282                   if (Parameter.ParameterKind == vapkRegister)
283                  {
284                      ModRM = 0xC0   |  RegisterToID(Parameter.Register); // 11000XXX
285                      SIB = 0 ;
286                      EnableSIB = false ;
287                      Displayment = false ;
288                       return   true ;
289                  }
290                   else
291                  {
292                      VBool DispZero = Parameter.Offset == 0   &&   ! Parameter.Linking.Enabled;
293                      VLE_AsmRegister Index = Parameter.Index;
294                      VLE_AsmRegister Base = Parameter.Base;
295                      VLE_AsmScale Scale = Parameter.Scale;
296                       if (Base == varNONE  &&  Scale == vas1)
297                      {
298                          Base = Index;
299                          Index = varNONE;
300                      }
301 
302                       if (Base == varNONE  &&  Index == varNONE) // disp32
303                      {
304                          ModRM = 0x05 ; // 00000101
305                          SIB = 0 ;
306                          EnableSIB = false ;
307                          Displayment = false ;
308                           return   true ;
309                      }
310                       if (Base != varNONE  &&  Index == varNONE  &&  DispZero) // [REG]
311                      {
312                          VByte ID = RegisterToID(Base);
313                           if (ID == 4 ) // [ESP]
314                          {
315                              ModRM = 0x04 ; // 00000100
316                              SIB = 0x24 ; // 00100100
317                              EnableSIB = true ;
318                              Displayment = true ;
319                               return   true ;
320                          }
321                           else   if (ID == 5 ) // [EBP]
322                          {
323                              ModRM = 0x85 ; // 10000101
324                              SIB = 0 ;
325                              EnableSIB = false ;
326                              Displayment = true ;
327                               return   true ;
328                          }
329                           else
330                          {
331                              ModRM = 0x00   |  ID; // 00000XXX
332                              SIB = 0 ;
333                              EnableSIB = false ;
334                              Displayment = false ;
335                               return   true ;
336                          }
337                      }
338                       if (Base != varNONE  &&  Index == varNONE  &&   ! DispZero) // [REG + disp32]
339                      {
340                          VByte ID = RegisterToID(Base);
341                           if (ID == 4 ) // [ESP + disp32]
342                          {
343                              ModRM = 0x84 ; // 10000100
344                              SIB = 0x24 ; // 00100100
345                              EnableSIB = true ;
346                              Displayment = true ;
347                               return   true ;
348                          }
349                           else
350                          {
351                              ModRM = 0x80   |  ID; // 10000XXX
352                              SIB = 0 ;
353                              EnableSIB = false ;
354                              Displayment = false ;
355                               return   true ;
356                          }
357                      }
358                       if (Base == varNONE  &&  Index != varNONE  &&  DispZero) // [REG * s]
359                      {
360                          ModRM = 0x04 ; // 00000100
361                          SIB = ScaleToSIB(Scale)  |  IndexToSIB(Index)  |  BaseToSIB(varEBP);
362                          EnableSIB = true ;
363                          Displayment = true ;
364                           return   true ;
365                      }
366                       if (Base != varNONE  &&  Index != varNONE  &&  DispZero) // [REG * s + REG]
367                      {
368                           if (Index == varESP)
369                               return   false ;
370                           if (Base == varEBP)
371                          {
372                              ModRM = 0x84 ; // 10000100
373                              SIB = ScaleToSIB(Scale)  |  IndexToSIB(Index)  |  BaseToSIB(Base);
374                              EnableSIB = true ;
375                              Displayment = true ;
376                               return   true ;
377                          }
378                           else
379                          {
380                              ModRM = 0x04 ; // 00000100
381                              SIB = ScaleToSIB(Scale)  |  IndexToSIB(Index)  |  BaseToSIB(Base);
382                              EnableSIB = true ;
383                              Displayment = false ;
384                               return   true ;
385                          }
386                      }
387                       if (Base == varNONE  &&  Index != varNONE  &&   ! DispZero) // [REG * s + disp32]
388                      {
389                           if (Index == varESP)
390                               return   false ;
391                          ModRM = 0x04 ; // 00000100
392                          SIB = ScaleToSIB(Scale)  |  IndexToSIB(Index)  |  BaseToSIB(Base);
393                          EnableSIB = true ;
394                          Displayment = true ;
395                           return   true ;
396                      }
397                       if (Base != varNONE  &&  Index != varNONE  &&   ! DispZero) // [REG * s + REG + disp32]
398                      {
399                           if (Index == varESP)
400                               return   false ;
401                          ModRM = 0x84 ; // 10000100
402                          SIB = ScaleToSIB(Scale)  |  IndexToSIB(Index)  |  BaseToSIB(Base);
403                          EnableSIB = true ;
404                          Displayment = true ;
405                           return   true ;
406                      }
407                       return   false ;
408                  }
409              }
410 
411  #define  APPEND_ERROR(ERRORCODE,MESSAGE)                        \
412              {                                                \
413                  VL_AsmError Error;                            \
414                  Error.ErrorCode = ERRORCODE;                    \
415                  Error.Index = i;                                \
416                  Error.Message = MESSAGE;                        \
417                  Compiled -> Errors.Add(Error);                \
418                   /* throw Error; */                             \
419                  CompileToBinaryCode = false ;                    \
420                   goto  EXIT_SINGLE_INSTRUCTION_COMPILATION;    \
421              }
422 
423               struct  LabelRef
424              {
425                  VSize            Position;     // 填补的位置
426                  VSize            InsBegin;     // 包含该位置的指令的起始地址
427                  VSize            InsEnd;         // 包含该位置的指令的结束地址
428                  VInt            LabelID;     // 标号
429              };
430 
431               struct  LinkingRef
432              {
433                  VInt            ID;
434                  VInt            Offset;
435                  VSize            Position;
436                  VByte            Bits;         // 0->8, 1->16, 2->32
437              };
438 
439              VL_AsmCompiled *  Compile(VL_AsmProgram *  Program)
440              {
441                  VL_AsmCompiled *                         Compiled = new  VL_AsmCompiled;     //  保存二进制代码的Compiled对象
442                  VL_ListedMap < VInt , VSize >             LabelOffsets;                     //  LabelID -> InstructionAddress
443                  VL_List < LabelRef ,  true >             LabelReferences;                 //  空缺的需要填补的Label相对地址
444                  VL_MultiMap < VInt , VInt ,  true >         LabelLookups;                     //  InstructionIndex -> LabelID
445                  VBool                                CompileToBinaryCode = true ;         //  是否将二进制代码写进Compiled对象
446 
447                  CopyStream( & Program -> ConstantBuffer, & Compiled -> ConstantBuffer);
448                   for (VInt i = 0 ;i < Program -> Labels.GetCount();i ++ )
449                  {
450                      LabelLookups.Add(Program -> Labels[i],i);
451                  }
452 
453                   for (VInt i = 0 ;i < Program -> Instructions.GetCount();i ++ )
454                  {
455                      VL_AsmIns &                 Instruction = Program -> Instructions[i];
456                      VL_List < VInt ,  true >*     AssociatedLabels = 0 ;
457                      {
458                          VInt Index = LabelLookups.IndexOfKey(i);
459                           if (Index >- 1 )
460                          {
461                              AssociatedLabels =& LabelLookups.ValueOfIndex(Index);
462                          }
463                      }
464 
465                      VLE_InsName    Name = NameToIns(Instruction.Name.Buffer());
466                       if (Name == vinUNKNOWN)
467                          APPEND_ERROR(vaecUnrecognizedName,L " 指令名\ "" +Instruction.Name+L " \ " 无法识别。 " );
468                       if (Instruction.ParameterCount < 0 || Instruction.ParameterCount > 4 )
469                          APPEND_ERROR(vaecWrongParameterCount,L " 指令的参数数量只能是0、1、2、3、4。 " );
470                       for (VInt j = 0 ;j < Instruction.ParameterCount;j ++ )
471                      {
472                          VL_AsmParameter &  Parameter = Instruction.Parameters[j];
473                           switch (Parameter.ParameterKind)
474                          {
475                           case  vapkRegister:
476                               if (Parameter.Register == varNONE)
477                              {
478                                  APPEND_ERROR(vaecLostRegister,L " 类型为寄存器的参数不可为varNONE。 " );
479                              }
480                               else   if (Parameter.Register >= varAL  &&  Parameter.Register <= varDH)
481                              {
482                                   if (Parameter.ParameterType != vaptInt8)
483                                      APPEND_ERROR(vaecWrongRegisterType,L " AL、AH、BL、BH、CL、CH、DL、DH的参数值类型必须是8位整数。 " );
484                              }
485                               else   if (Parameter.Register >= varAX  &&  Parameter.Register <= varDI)
486                              {
487                                   if (Parameter.ParameterType != vaptInt16)
488                                      APPEND_ERROR(vaecWrongRegisterType,L " AX、BX、CX、DS、SP、BP、SI、DI的参数值类型必须是16位整数。 " );
489                              }
490                               else   if (Parameter.Register >= varEAX  &&  Parameter.Register <= varEDI)
491                              {
492                                   if (Parameter.ParameterType != vaptInt32)
493                                      APPEND_ERROR(vaecWrongRegisterType,L " EAX、EBX、ECX、EDS、ESP、EBP、ESI、EDI的参数值类型必须是32位整数。 " );
494                              }
495                               else   if (Parameter.Register >= varST0  &&  Parameter.Register <= varST7)
496                              {
497                                   if (Parameter.ParameterType != vaptFpReg)
498                                      APPEND_ERROR(vaecWrongRegisterType,L " 浮点寄存器ST(i)的参数值类型必须是与位数无关的浮点数。 " );
499                              }
500                               else
501                              {
502                                  APPEND_ERROR(vaecUnrecognizedRegister,L " 未知寄存器。 " );
503                              }
504                               break ;
505                           case  vapkPointer:
506                               if (Parameter.Index != varNONE  &&  (Parameter.Index < varEAX  ||  Parameter.Index > varEDI))
507                                  APPEND_ERROR(vaecIndexRegisterMustBe32Bits,L " Index寄存器只能是EAX、EBX、ECX、EDS、ESP、EBP、ESI、EDI。 " );
508                               if (Parameter.Base != varNONE  &&  (Parameter.Base < varEAX  ||  Parameter.Base > varEDI))
509                                  APPEND_ERROR(vaecBaseRegisterMustBe32Bits,L " Base寄存器只能是EAX、EBX、ECX、EDS、ESP、EBP、ESI、EDI。 " );
510                               if (Parameter.Scale < vas1  ||  Parameter.Scale > vas4)
511                                  APPEND_ERROR(vaecUnrecognizedScale,L " Scale只能是1、2、4、8。 " );
512                               switch (Parameter.ParameterType)
513                              {            
514                               case  vaptInt8:
515                               case  vaptInt16:
516                               case  vaptInt32:
517                               case  vaptFp32:
518                               case  vaptFp64:
519                                   break ;
520                               default :
521                                  APPEND_ERROR(vaecUnrecognizedType,L " 指针的参数值类型只能是8位、16位、32位整数或32位、64位浮点数。 " );
522                              }
523                               break ;
524                           case  vapkSigned:
525                               switch (Parameter.ParameterType)
526                              {
527                               case  vaptInt8:
528                                   if (Parameter.Linking.Enabled == false   &&  (Parameter.Signed <- 128   ||  Parameter.Signed > 127 ))
529                                      APPEND_ERROR(vaecSignedOutOfRange,L " 有符号整数\ "" +VUnicodeString(Parameter.Signed)+L " \ " 超出了8位有符号整数的描述范围。 " );
530                                   break ;
531                               case  vaptInt16:
532                                   if (Parameter.Linking.Enabled == false   &&  (Parameter.Signed <- 32768   ||  Parameter.Signed > 32767 ))
533                                      APPEND_ERROR(vaecSignedOutOfRange,L " 有符号整数\ "" +VUnicodeString(Parameter.Signed)+L " \ " 超出了16位有符号整数的描述范围。 " );
534                                   break ;
535                               case  vaptInt32:
536                                   break ;
537                               default :
538                                  APPEND_ERROR(vaecSignedMustBeInteger,L " 有符号整数的参数值类型只能是8位、16位、32位的有符号整数。 " );
539                              }
540                               break ;
541                           case  vapkUnsigned:
542                               switch (Parameter.ParameterType)
543                              {
544                               case  vaptInt8:
545                                   if (Parameter.Linking.Enabled == false   &&  Parameter.Unsigned > 255 )
546                                  {
547                                      VWChar Buffer[ 64 ] = { 0 };
548                                      _ui64tow(Parameter.Unsigned,Buffer, 10 );
549                                      APPEND_ERROR(vaecUnsignedOutOfRange,L " 无符号整数\ "" +VUnicodeString(Buffer)+L " \ " 超出了8位无符号整数的描述范围。 " );
550                                  }
551                                   break ;
552                               case  vaptInt16:
553                                   if (Parameter.Linking.Enabled == false   &&  Parameter.Unsigned > 65535 )
554                                  {
555                                      VWChar Buffer[ 64 ] = { 0 };
556                                      _ui64tow(Parameter.Unsigned,Buffer, 10 );
557                                      APPEND_ERROR(vaecUnsignedOutOfRange,L " 无符号整数\ "" +VUnicodeString(Buffer)+L " \ " 超出了16位无符号整数的描述范围。 " );
558                                  }
559                                   break ;
560                               case  vaptInt32:
561                                   break ;
562                               default :
563                                  APPEND_ERROR(vaecUnsignedMustBeInteger,L " 无符号整数的参数值类型只能是8位、16位、32位的无符号整数。 " );
564                              }
565                               break ;
566                           case  vapkRelative:
567                               switch (Parameter.ParameterType)
568                              {
569                               case  vaptInt8:
570                                   if (Parameter.Linking.Enabled == false   &&  (Parameter.Signed <- 128   ||  Parameter.Signed > 127 ))
571                                      APPEND_ERROR(vaecSignedOutOfRange,L " 相对地址\ "" +VUnicodeString(Parameter.Signed)+L " \ " 超出了8位有符号整数的描述范围。 " );
572                                   break ;
573                               case  vaptInt16:
574                                   if (Parameter.Linking.Enabled == false   &&  (Parameter.Signed <- 32768   ||  Parameter.Signed > 32767 ))
575                                      APPEND_ERROR(vaecSignedOutOfRange,L " 相对地址\ "" +VUnicodeString(Parameter.Signed)+L " \ " 超出了16位有符号整数的描述范围。 " );
576                                   break ;
577                               case  vaptInt32:
578                                   break ;
579                               default :
580                                  APPEND_ERROR(vaecRelativeMustBeInteger,L " 相对地址的参数值类型只能是8位、16位、32位的有符号整数。 " );
581                              }
582                               break ;
583                           case  vapkLabel:
584                               if (Parameter.ParameterType != vaptInt32)
585                                  APPEND_ERROR(vaecLabelMustBeInt32,L " 标号的参数值类型必须是32位整数。 " );
586                               if (Parameter.Label < 0   ||  Parameter.Label >= Program -> Labels.GetCount())
587                                  APPEND_ERROR(vaecUnrecognizedLabel,L " 标号不存在。 " );
588                               break ;
589                           default :
590                              APPEND_ERROR(vaecUnrecognizedKind,L " 参数类型只能是寄存器、指针、有符号整数、无符号整数、相对地址偏移或标号 " );
591                          }
592                      }
593                      
594                      VInt InsMin = InsOffset[Name];
595                      VInt InsMax = InsMin + InsCount[Name] - 1 ;
596                      VInt SelectedIns =- 1 ;
597                       for (VInt j = InsMin;j <= InsMax;j ++ )
598                      {
599                          VLS_InsFormat &  Format = InsFormat[j];
600                          VBool Failed = false ;
601                           for (VInt k = 0 ;k < Instruction.ParameterCount;k ++ )
602                          {
603                               if ( ! CheckParameter(Format.Params[k],Instruction.Parameters[k]))
604                              {
605                                  Failed = true ;
606                                   break ;
607                              }
608                          }
609                           for (VInt k = Instruction.ParameterCount;k < 4 ;k ++ )
610                          {
611                               if (Format.Params[k] != vipNoParam)
612                              {
613                                  Failed = true ;
614                                   break ;
615                              }
616                          }
617                           if ( ! Failed)
618                          {
619                              SelectedIns = j;
620                               break ;
621                          }
622                      }
623                       if (SelectedIns ==- 1 )
624                          APPEND_ERROR(vaecParameterNotMatched,L " 没有可以用于此参数类型组合的指令。 " );
625 
626                      {
627                          VBool UseModRM = false ;
628                          VInt ModRMIndex =- 1 ;
629                          VInt ExtRegIndex =- 1 ;
630                          VInt Ext =- 1 ;
631                          VInt PlusIndex =- 1 ;
632                          VInt ImmIndex =- 1 ;
633                          VBool Used[ 4 ] = { false , false , false , false };
634                          VLS_InsFormat &  Format = InsFormat[SelectedIns];
635 
636                           if (Format.Plus == vipRegister)
637                          {
638                              PlusIndex = FindRI(Format,Used);
639                               if (PlusIndex ==- 1 )
640                                  APPEND_ERROR(vaecDoNotKnowHowToCompile,L " 找不到Plus的对应参数。 " );
641                          }
642                           else   if (Format.Plus == vipFloat)
643                          {
644                              PlusIndex = FindRF(Format,Used);
645                               if (PlusIndex ==- 1 )
646                                  APPEND_ERROR(vaecDoNotKnowHowToCompile,L " 找不到Plus的对应参数。 " );
647                          }
648 
649                           if (Format.Imm == viiNoImm)
650                          {
651                              ImmIndex = FindIMM(Format,Used);
652                               if (ImmIndex !=- 1 )
653                              {
654                                   if (Format.Params[ImmIndex] == vipCONST_1  ||  Format.Params[ImmIndex] == vipCONST_3)
655                                  {
656                                      ImmIndex =- 1 ;
657                                  }
658                              }
659                          }
660                           else
661                          {
662                              ImmIndex = FindIMM(Format,Used);
663                               if (ImmIndex ==- 1 )
664                                  APPEND_ERROR(vaecDoNotKnowHowToCompile,L " 找不到Immediate的对应参数。 " );
665                          }
666 
667                           if (Format.Ext >= vie0  &&  Format.Ext <= vie7)
668                          {
669                              UseModRM = true ;
670                              Ext = Format.Ext;
671                          }
672                           else   if (Format.Ext == vieRegister)
673                          {
674                              UseModRM = true ;
675                              ExtRegIndex = FindRI(Format,Used);
676                               if (ExtRegIndex ==- 1 )
677                                  APPEND_ERROR(vaecDoNotKnowHowToCompile,L " 找不到/r的对应参数。 " );
678                              Ext = RegisterToExt(Instruction.Parameters[ExtRegIndex].Register);
679                          }
680 
681                          ModRMIndex = FindRM(Format,Used);
682                           if (ModRMIndex !=- 1 )
683                          {
684                               if (Format.Params[ModRMIndex] >= vipAL  &&  Format.Params[ModRMIndex] <= vipSS)
685                              {
686                                  ModRMIndex =- 1 ;
687                              }
688                               else
689                              {
690                                   if ( ! UseModRM)
691                                  {
692                                      UseModRM = true ;
693                                  }
694                                   if (Ext ==- 1 )
695                                  {
696                                      ExtRegIndex = FindRI(Format,Used);
697                                       if (ExtRegIndex !=- 1 )
698                                      {
699                                           if (Format.Params[ExtRegIndex] >= vipAL  &&  Format.Params[ExtRegIndex] <= vipSS)
700                                          {
701                                              ExtRegIndex =- 1 ;
702                                          }
703                                           else
704                                          {
705                                              Ext = RegisterToExt(Instruction.Parameters[ExtRegIndex].Register);
706                                          }
707                                      }
708                                  }
709                              }
710                          }
711 
712                           for (VInt j = 0 ;j < Instruction.ParameterCount;j ++ )
713                          {
714                               if ( ! Used[j])
715                                  APPEND_ERROR(vaecDoNotKnowHowToCompile,L " 找不到第\ "" +VUnicodeString(j+1)+L " \ " 个参数的二进制码贡献方法 " );
716                          }
717                           if (CompileToBinaryCode)
718                          {
719                              VSize InstructionBeginPosition = Compiled -> InstructionBuffer.Position();
720                               if (AssociatedLabels)
721                              {
722                                   for (VInt j = 0 ;j < AssociatedLabels -> GetCount();j ++ )
723                                  {
724                                      LabelOffsets.Add(( * AssociatedLabels)[j],InstructionBeginPosition);
725                                  }
726                              }
727                               if (Format.Prefix16)
728                              {
729                                  VByte Prefix = 0x66 ;
730                                  Compiled -> InstructionBuffer.Write( & Prefix, sizeof (Prefix));
731                              }
732                               if (PlusIndex ==- 1 )
733                              {
734                                  Compiled -> InstructionBuffer.Write((VPointer)Format.Opcode,Format.OpcodeLength);
735                              }
736                               else
737                              {
738                                  Compiled -> InstructionBuffer.Write((VPointer)Format.Opcode,Format.OpcodeLength - 1 );
739                                  VByte OpCode = Format.Opcode[Format.OpcodeLength - 1 ];
740                                  OpCode += (VByte)RegisterToExt(Instruction.Parameters[PlusIndex].Register);
741                                  Compiled -> InstructionBuffer.Write( & OpCode, sizeof (OpCode));
742                              }
743                               if (UseModRM)
744                              {
745                                  VByte ModRM = 0 ;
746                                  VByte SIB = 0 ;
747                                  VBool EnableSIB = false ;
748                                  VBool Displayment = false ;
749                                  VL_AsmParameter &  Parameter = Instruction.Parameters[ModRMIndex];
750 
751                                   if (MakeModRMWithoutExt(Parameter,ModRM,SIB,EnableSIB,Displayment))
752                                  {
753                                      ModRM |= (VByte)(Ext << 3 );
754                                      Compiled -> InstructionBuffer.Write( & ModRM, sizeof (ModRM));
755                                       if (EnableSIB)
756                                      {
757                                          Compiled -> InstructionBuffer.Write( & SIB, sizeof (SIB));
758                                      }
759                                       if (Displayment)
760                                      {
761                                          VInt32s Disp32 = Parameter.Offset;
762                                           if (Parameter.Linking.Enabled)
763                                          {
764                                              LinkingRef Ref;
765                                              Ref.Position = Compiled -> InstructionBuffer.Position();
766                                              Ref.ID = Parameter.Linking.LinkingID;
767                                              Ref.Offset = Parameter.Linking.LinkingOffset;
768                                              Ref.Bits = 2 ;
769                                              Compiled -> LinkingBuffer.Write( & Ref, sizeof (Ref));
770                                          }
771                                          Compiled -> InstructionBuffer.Write( & Disp32, sizeof (Disp32));
772                                      }
773                                  }
774                                   else
775                                  {
776                                      APPEND_ERROR(vaecDoNotKnowHowToCompile,L " 无法将参数中的寄存器表达的指针转换成ModR/M+SIB字节。 " );
777                                  }
778                              }
779                               if (ImmIndex !=- 1 )
780                              {
781                                  VL_AsmParameter &  Parameter = Instruction.Parameters[ImmIndex];
782                                  VLE_AsmParameterKind Kind = Parameter.ParameterKind;
783                                   if (Parameter.Linking.Enabled)
784                                  {
785                                      LinkingRef Ref;
786                                      Ref.Position = Compiled -> InstructionBuffer.Position();
787                                      Ref.ID = Parameter.Linking.LinkingID;
788                                      Ref.Offset = Parameter.Linking.LinkingOffset;
789                                       switch (Parameter.ParameterType)
790                                      {
791                                       case  vaptInt8:
792                                          Ref.Bits = 0 ;
793                                           break ;
794                                       case  vaptInt16:
795                                          Ref.Bits = 1 ;
796                                           break ;
797                                       case  vaptInt32:
798                                       default :
799                                          Ref.Bits = 2 ;
800                                           break ;
801                                      }
802                                      Compiled -> LinkingBuffer.Write( & Ref, sizeof (Ref));
803                                  }
804                                   else   if (Kind == vapkLabel)
805                                  {
806                                      LabelRef Ref;
807                                      Ref.Position = Compiled -> InstructionBuffer.Position();
808                                      Ref.InsBegin = InstructionBeginPosition;
809                                      Ref.InsEnd = Compiled -> InstructionBuffer.Position() + sizeof (VInt32u);
810                                      Ref.LabelID = Parameter.Label;
811                                      LabelReferences.Add(Ref);
812                                  }
813                                   switch (Parameter.ParameterType)
814                                  {
815                                   case  vaptInt8:
816                                      {
817                                          VInt8s Data = Kind == vapkSigned ? (VInt8s)Parameter.Signed:(VInt8s)Parameter.Unsigned;
818                                          Compiled -> InstructionBuffer.Write( & Data, sizeof (Data));
819                                      }
820                                       break ;
821                                   case  vaptInt16:
822                                      {
823                                          VInt16s Data = Kind == vapkSigned ? (VInt16s)Parameter.Signed:(VInt16s)Parameter.Unsigned;
824                                          Compiled -> InstructionBuffer.Write( & Data, sizeof (Data));
825                                      }
826                                       break ;
827                                   case  vaptInt32:
828                                   default :
829                                      {
830                                          VInt32s Data = Kind == vapkSigned ? (VInt32s)Parameter.Signed:(VInt32s)Parameter.Unsigned;
831                                          Compiled -> InstructionBuffer.Write( & Data, sizeof (Data));
832                                      }
833                                       break ;
834                                  }
835                              }
836                          }
837                      }
838  EXIT_SINGLE_INSTRUCTION_COMPILATION:
839                      ;
840                  }
841 
842                   if ( ! Compiled -> Errors.GetCount())
843                  {
844                       for (VInt i = 0 ;i < LabelReferences.GetCount();i ++ )
845                      {
846                          LabelRef &  Ref = LabelReferences[i];
847                          VSize Address = LabelOffsets[Ref.LabelID];
848                           if (Address <= Ref.InsBegin)
849                          {
850                              Address = Address - Ref.InsEnd;
851                          }
852                           else   if (Address >= Ref.InsEnd)
853                          {
854                              Address = Address - Ref.InsEnd;
855                          }
856                           else
857                          {
858                               throw   " Label地址位于本指令中间,有BUG。 " ;
859                          }
860                          Compiled -> InstructionBuffer.SeekFromBegin(Ref.Position);
861                          VInt32s Address32 = (VInt32s)Address;
862                          Compiled -> InstructionBuffer.Write( & Address32, sizeof (Address32));
863                      }
864                  }
865 
866                  Compiled -> ConstantBuffer.SeekFromBegin( 0 );
867                  Compiled -> InstructionBuffer.SeekFromBegin( 0 );
868                  Compiled -> LinkingBuffer.SeekFromBegin( 0 );
869                   return  Compiled;
870              }
871 
872  #undef  APPEND_ERROR
873 
874          }
875      }
876  }

    在if(SelectedIns==-1) APPEND_ERROR(vaecParameterNotMatched,L"没有可以用于此参数类型组合的指令。");这句下面的APPEND_ERROR大部分是为了调试写的,基本上如果促触发了DoNotKnowHowToCompile错误的话,9成都是这个汇编器有BUG。

    汇编器的核心部分顺利完成。接下来的工作是写一个汇编语言的编译器,以便手写大量test case进行自动测试。

你可能感兴趣的:(JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用)