中間指令主要用于解決以下問題:
1、不同大小的整數、浮點、指針的互相轉換和計算
2、寄存器分配
3、跳轉
4、調用轉換(stdcall、cdecl、fastcall)
5、臨時存儲單位(變量等)
因此指令在設計的時候需要
1、不讓用戶知道東西是放在哪里的(沒有堆棧給你push和pop,而且變量在物理上不一定存在,譬如說可能在寄存器里面,或者直接優化沒了等等)
2、不讓用戶接觸到各種標志位(譬如說那個惡心的浮點比較)
3、不讓用戶接觸到stdcall、cdecl和fastcall的區別(因此call指令需要將所有參數一起寫入,而不是在之前push)
4、不讓用戶接觸不同類型數據的轉換過程(全自動處理,就算你int32=fp32+int16,也是一條指令。)
5、為了保持靈活性,聲明變量的時候只指出其大小,在使用變量的每一處地方標記類型(因此可以在不同的地方標記為不同的,可以救急)
于是各種x86的特性就被消滅掉了,下面給個例子(
草稿):
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
將草稿確定下來之后,先寫一個不優化的編譯器從這個指令翻譯到x86,就可以開始做實驗了。
posted on 2009-03-10 21:05
陳梓瀚(vczh) 閱讀(1815)
評論(0) 編輯 收藏 引用 所屬分類:
JIT