JIT脚本引擎:成功将第一个脚本编译成机器码
这次工作将一个中间语言的程序翻译成了汇编,然后再翻译成机器码。这一次产生的汇编比较烂,到时候做个窥孔优化稍微处理一下就好了。等上层的设施搞定之后再将这个中间语言到汇编的程序重写。下面是一个菲薄纳气数列的例子。
1:中间代码。这是一个菲薄纳气函数的中间指令。
1
FUNCTION
4
fab STDCALL
2 PARAM 4 number
3 BEGIN
4 BLOCK
5 VAR 4 compare_result
6 BEGIN
7 LT int32s compare_result, int32s number, int32s 2
8 JBF int32s compare_result, @COMBINE
9 MOV int32s #RETURN_VALUE, int32s 1
10 JE @COMBINE
11 BLOCK @COMBINE
12 VAR 4 a
13 VAR 4 b
14 VAR 4 c
15 BEGIN
16 MOV int32s a, int32s 1
17 MOV int32s b, int32s 1
18 BLOCK @LOOP
19 BEGIN
20 ADD int32s c, int32s a, int32s b
21 MOV int32s a, int32s b
22 MOV int32s b, int32s c
23 SUB int32s number, int32s number, int32s 1
24 LT int32s compare_result, int32s number, int32s 2
25 JET int32s compare_result, @LOOP
26 JB @LOOP
27 END BLOCK
28 MOV int32s #RETURN_VALUE, int32s b
29 END BLOCK
30 END BLOCK
31 END FUNCTION
2 PARAM 4 number
3 BEGIN
4 BLOCK
5 VAR 4 compare_result
6 BEGIN
7 LT int32s compare_result, int32s number, int32s 2
8 JBF int32s compare_result, @COMBINE
9 MOV int32s #RETURN_VALUE, int32s 1
10 JE @COMBINE
11 BLOCK @COMBINE
12 VAR 4 a
13 VAR 4 b
14 VAR 4 c
15 BEGIN
16 MOV int32s a, int32s 1
17 MOV int32s b, int32s 1
18 BLOCK @LOOP
19 BEGIN
20 ADD int32s c, int32s a, int32s b
21 MOV int32s a, int32s b
22 MOV int32s b, int32s c
23 SUB int32s number, int32s number, int32s 1
24 LT int32s compare_result, int32s number, int32s 2
25 JET int32s compare_result, @LOOP
26 JB @LOOP
27 END BLOCK
28 MOV int32s #RETURN_VALUE, int32s b
29 END BLOCK
30 END BLOCK
31 END FUNCTION
2:编译后的汇编代码(编译成机器码后使用Visual Studio 2008 Team System进行反汇编)
1
000B0000 FF F5 push ebp
2 000B0002 89 E5 mov ebp,esp
3 000B0004 81 EC 1C 00 00 00 sub esp,1Ch
4 000B000A 60 pushad
5 000B000B B8 02 00 00 00 mov eax, 2
6 000B0010 89 C2 mov edx,eax
7 000B0012 8B 85 08 00 00 00 mov eax,dword ptr [ebp + 00000008h]
8 000B0018 31 FF xor edi,edi
9 000B001A B9 01 00 00 00 mov ecx, 1
10 000B001F 39 D0 cmp eax,edx
11 000B0021 0F 4C F9 cmovl edi,ecx
12 000B0024 89 F8 mov eax,edi
13 000B0026 89 85 EC FF FF FF mov dword ptr [ebp + FFFFFFECh],eax
14 000B002C 8B 85 EC FF FF FF mov eax,dword ptr [ebp + FFFFFFECh]
15 000B0032 A9 FF FF FF FF test eax,0FFFFFFFFh
16 000B0037 0F 84 10 00 00 00 je 000B004D
17 000B003D B8 01 00 00 00 mov eax, 1
18 000B0042 89 85 FC FF FF FF mov dword ptr [ebp + FFFFFFFCh],eax
19 000B0048 E9 9C 00 00 00 jmp 000B00E9
20 000B004D B8 01 00 00 00 mov eax, 1
21 000B0052 89 85 F0 FF FF FF mov dword ptr [ebp + FFFFFFF0h],eax
22 000B0058 B8 01 00 00 00 mov eax, 1
23 000B005D 89 85 F4 FF FF FF mov dword ptr [ebp + FFFFFFF4h],eax
24 000B0063 8B 85 F4 FF FF FF mov eax,dword ptr [ebp + FFFFFFF4h]
25 000B0069 89 C2 mov edx,eax
26 000B006B 8B 85 F0 FF FF FF mov eax,dword ptr [ebp + FFFFFFF0h]
27 000B0071 01 D0 add eax,edx
28 000B0073 89 85 F8 FF FF FF mov dword ptr [ebp + FFFFFFF8h],eax
29 000B0079 8B 85 F4 FF FF FF mov eax,dword ptr [ebp + FFFFFFF4h]
30 000B007F 89 85 F0 FF FF FF mov dword ptr [ebp + FFFFFFF0h],eax
31 000B0085 8B 85 F8 FF FF FF mov eax,dword ptr [ebp + FFFFFFF8h]
32 000B008B 89 85 F4 FF FF FF mov dword ptr [ebp + FFFFFFF4h],eax
33 000B0091 B8 01 00 00 00 mov eax, 1
34 000B0096 89 C2 mov edx,eax
35 000B0098 8B 85 08 00 00 00 mov eax,dword ptr [ebp + 00000008h]
36 000B009E 29 D0 sub eax,edx
37 000B00A0 89 85 08 00 00 00 mov dword ptr [ebp + 00000008h],eax
38 000B00A6 B8 02 00 00 00 mov eax, 2
39 000B00AB 89 C2 mov edx,eax
40 000B00AD 8B 85 08 00 00 00 mov eax,dword ptr [ebp + 00000008h]
41 000B00B3 31 FF xor edi,edi
42 000B00B5 B9 01 00 00 00 mov ecx, 1
43 000B00BA 39 D0 cmp eax,edx
44 000B00BC 0F 4C F9 cmovl edi,ecx
45 000B00BF 89 F8 mov eax,edi
46 000B00C1 89 85 EC FF FF FF mov dword ptr [ebp + FFFFFFECh],eax
47 000B00C7 8B 85 EC FF FF FF mov eax,dword ptr [ebp + FFFFFFECh]
48 000B00CD A9 FF FF FF FF test eax,0FFFFFFFFh
49 000B00D2 0F 85 05 00 00 00 jne 000B00DD
50 000B00D8 E9 86 FF FF FF jmp 000B0063
51 000B00DD 8B 85 F4 FF FF FF mov eax,dword ptr [ebp + FFFFFFF4h]
52 000B00E3 89 85 FC FF FF FF mov dword ptr [ebp + FFFFFFFCh],eax
53 000B00E9 8B 85 FC FF FF FF mov eax,dword ptr [ebp + FFFFFFFCh]
54 000B00EF 89 EC mov esp,ebp
55 000B00F1 8F C5 pop ebp
56 000B00F3 C2 04 00 ret 4
2 000B0002 89 E5 mov ebp,esp
3 000B0004 81 EC 1C 00 00 00 sub esp,1Ch
4 000B000A 60 pushad
5 000B000B B8 02 00 00 00 mov eax, 2
6 000B0010 89 C2 mov edx,eax
7 000B0012 8B 85 08 00 00 00 mov eax,dword ptr [ebp + 00000008h]
8 000B0018 31 FF xor edi,edi
9 000B001A B9 01 00 00 00 mov ecx, 1
10 000B001F 39 D0 cmp eax,edx
11 000B0021 0F 4C F9 cmovl edi,ecx
12 000B0024 89 F8 mov eax,edi
13 000B0026 89 85 EC FF FF FF mov dword ptr [ebp + FFFFFFECh],eax
14 000B002C 8B 85 EC FF FF FF mov eax,dword ptr [ebp + FFFFFFECh]
15 000B0032 A9 FF FF FF FF test eax,0FFFFFFFFh
16 000B0037 0F 84 10 00 00 00 je 000B004D
17 000B003D B8 01 00 00 00 mov eax, 1
18 000B0042 89 85 FC FF FF FF mov dword ptr [ebp + FFFFFFFCh],eax
19 000B0048 E9 9C 00 00 00 jmp 000B00E9
20 000B004D B8 01 00 00 00 mov eax, 1
21 000B0052 89 85 F0 FF FF FF mov dword ptr [ebp + FFFFFFF0h],eax
22 000B0058 B8 01 00 00 00 mov eax, 1
23 000B005D 89 85 F4 FF FF FF mov dword ptr [ebp + FFFFFFF4h],eax
24 000B0063 8B 85 F4 FF FF FF mov eax,dword ptr [ebp + FFFFFFF4h]
25 000B0069 89 C2 mov edx,eax
26 000B006B 8B 85 F0 FF FF FF mov eax,dword ptr [ebp + FFFFFFF0h]
27 000B0071 01 D0 add eax,edx
28 000B0073 89 85 F8 FF FF FF mov dword ptr [ebp + FFFFFFF8h],eax
29 000B0079 8B 85 F4 FF FF FF mov eax,dword ptr [ebp + FFFFFFF4h]
30 000B007F 89 85 F0 FF FF FF mov dword ptr [ebp + FFFFFFF0h],eax
31 000B0085 8B 85 F8 FF FF FF mov eax,dword ptr [ebp + FFFFFFF8h]
32 000B008B 89 85 F4 FF FF FF mov dword ptr [ebp + FFFFFFF4h],eax
33 000B0091 B8 01 00 00 00 mov eax, 1
34 000B0096 89 C2 mov edx,eax
35 000B0098 8B 85 08 00 00 00 mov eax,dword ptr [ebp + 00000008h]
36 000B009E 29 D0 sub eax,edx
37 000B00A0 89 85 08 00 00 00 mov dword ptr [ebp + 00000008h],eax
38 000B00A6 B8 02 00 00 00 mov eax, 2
39 000B00AB 89 C2 mov edx,eax
40 000B00AD 8B 85 08 00 00 00 mov eax,dword ptr [ebp + 00000008h]
41 000B00B3 31 FF xor edi,edi
42 000B00B5 B9 01 00 00 00 mov ecx, 1
43 000B00BA 39 D0 cmp eax,edx
44 000B00BC 0F 4C F9 cmovl edi,ecx
45 000B00BF 89 F8 mov eax,edi
46 000B00C1 89 85 EC FF FF FF mov dword ptr [ebp + FFFFFFECh],eax
47 000B00C7 8B 85 EC FF FF FF mov eax,dword ptr [ebp + FFFFFFECh]
48 000B00CD A9 FF FF FF FF test eax,0FFFFFFFFh
49 000B00D2 0F 85 05 00 00 00 jne 000B00DD
50 000B00D8 E9 86 FF FF FF jmp 000B0063
51 000B00DD 8B 85 F4 FF FF FF mov eax,dword ptr [ebp + FFFFFFF4h]
52 000B00E3 89 85 FC FF FF FF mov dword ptr [ebp + FFFFFFFCh],eax
53 000B00E9 8B 85 FC FF FF FF mov eax,dword ptr [ebp + FFFFFFFCh]
54 000B00EF 89 EC mov esp,ebp
55 000B00F1 8F C5 pop ebp
56 000B00F3 C2 04 00 ret 4
附上Visual Studio 2008 Team System的截图:
最后是执行结果(将函数指针拿出来,然后使用不同的参数进行调用):
接下来就是漫长的调试工作了……