随笔-341  评论-2670  文章-0  trackbacks-0
    在完成了这里这里的工作之后,就可以写程序生成机器码了。在生成机器码的时候有如下注意事项:

    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捕获:

    按CTRL+ALT+D进入汇编窗口以便跟踪(代码窗口不能单步进CALL):

    执行到CALL EAX的时候按F11进入我们写程序生成的代码:

    这里我们可以看到,程序产生的结果是正确的。于是CPU将顺利执行这段代码,最后将EAX变为55:

    到这里就结束了。以下是汇编器的源代码的核心部分。首先是结构的声明:
  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进行自动测试。
posted on 2009-02-22 07:08 陈梓瀚(vczh) 阅读(4904) 评论(11)  编辑 收藏 引用 所属分类: JIT

评论:
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-22 07:14 | S.l.e!ep.¢%
楼主用的IDE 是?  回复  更多评论
  
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-22 08:19 | 陈梓瀚(vczh)
@S.l.e!ep.¢%
Visual Studio 2008 Team System  回复  更多评论
  
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-22 08:19 | 锅炉
你的代码是手写,还是用什么工具生成?
写代码的速度实在是太快了,疑惑啊  回复  更多评论
  
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-22 08:20 | 陈梓瀚(vczh)
@锅炉
没有规律的代码还能生成么,当然是要手写的。  回复  更多评论
  
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-22 20:10 | SOS
@锅炉
程序员第一预科乃多人聊天,手速speed up  回复  更多评论
  
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-22 20:28 | WTL
VCZH真的很牛,要是能向POCO贡献cross GUI就好了  回复  更多评论
  
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-22 21:26 | 空明流转
@WTL
楼主这个混蛋从来都猥琐在Windows平台上。  回复  更多评论
  
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-22 22:24 | 陈梓瀚(vczh)
@WTL
我是单一编译器单一操作系统派。  回复  更多评论
  
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-22 22:24 | kuafoo
现在才了解到虚拟机原来是这样执行编译后的代码的啊
楼主怎么不把源码打包放出来,让我们也爽上一把  回复  更多评论
  
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-22 22:28 | 陈梓瀚(vczh)
@kuafoo
其实不这样执行也是可以的,可以用C++模拟,只是觉得不过瘾于是干脆就编译到x86上面了。源代码等做完了再放。  回复  更多评论
  
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-26 01:45 | baihacker
# re: JIT脚本引擎:将汇编语言编译成机器码写进内存并在C++中调用 2009-02-23 13:26 | 空明流转

@WTL
楼主这个混蛋从来都猥琐在Windows平台上。 回复 更多评论  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理