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 }
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
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 }
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进行自动测试。