中間指令主要用于解決以下問題:
1、不同大小的整數(shù)、浮點(diǎn)、指針的互相轉(zhuǎn)換和計(jì)算
2、寄存器分配
3、跳轉(zhuǎn)
4、調(diào)用轉(zhuǎn)換(stdcall、cdecl、fastcall)
5、臨時(shí)存儲單位(變量等)
因此指令在設(shè)計(jì)的時(shí)候需要
1、不讓用戶知道東西是放在哪里的(沒有堆棧給你push和pop,而且變量在物理上不一定存在,譬如說可能在寄存器里面,或者直接優(yōu)化沒了等等)
2、不讓用戶接觸到各種標(biāo)志位(譬如說那個(gè)惡心的浮點(diǎn)比較)
3、不讓用戶接觸到stdcall、cdecl和fastcall的區(qū)別(因此call指令需要將所有參數(shù)一起寫入,而不是在之前push)
4、不讓用戶接觸不同類型數(shù)據(jù)的轉(zhuǎn)換過程(全自動處理,就算你int32=fp32+int16,也是一條指令。)
5、為了保持靈活性,聲明變量的時(shí)候只指出其大小,在使用變量的每一處地方標(biāo)記類型(因此可以在不同的地方標(biāo)記為不同的,可以救急)
于是各種x86的特性就被消滅掉了,下面給個(gè)例子(
草稿):
1 FUNCTION 32 fab stdcall
2 PARAM 32 number
3 BLOCK
4 VAR 32 compare_result
5 BEGIN
6 LT int32 compare_result, int32 number, int32 2
7 JBF int32 compare_result, @COMBINE
8 MOV int32 #RESULT_VALUE, int32 1
9 JE @COMBINE
10 BLOCK @COMBINE
11 VAR 32 difference
12 VAR 32 n_1
13 VAR 32 n_2
14 BEGIN
15 SUB int32 difference, int32 number, int32 1
16 CALLF int32 n_1, fab, int32 difference
17 SUB int32 difference, int32 number, int32 2
18 CALLF int32 n_2, fab, int32 difference
19 ADD int32 #RESULT_VALUE, int32 n_1, int32 n_2
20 END BLOCK
21 END BLOCK
22
23 FUNCTION 32 fab stdcall
24 PARAM 32 number
25 BLOCK
26 VAR 32 compare_result
27 BEGIN
28 LT int32 compare_result, int32 number, int32 2
29 JBF int32 compare_result, @COMBINE
30 MOV int32 #RESULT_VALUE, int32 1
31 JE @COMBINE
32 BLOCK @COMBINE
33 VAR 32 a
34 VAR 32 b
35 VAR 32 c
36 BEGIN
37 MOV int32 a, int32 1
38 MOV int32 b, int32 1
39 SUB int32 number, int32 number, int32 1
40 BEGIN @LOOP
41 BEGIN
42 LT int32 compare_result, int32 number, int32 2
43 JEF int32 compare_result, @LOOP
44 ADD int32 c, int32 a, int32 b
45 MOV int32 a, int32 b
46 MOV int32 b, int32 c
47 SUB int32 number, int32 number, int32 1
48 JB @LOOP
49 END LOOP
50 MOV int32 #RESULT_VALUE, int32 b
51 END BLOCK
52 END BLOCK
將草稿確定下來之后,先寫一個(gè)不優(yōu)化的編譯器從這個(gè)指令翻譯到x86,就可以開始做實(shí)驗(yàn)了。
posted on 2009-03-10 21:05
陳梓瀚(vczh) 閱讀(1824)
評論(0) 編輯 收藏 引用 所屬分類:
JIT