中间指令主要用于解决以下问题:
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) 阅读(1800)
评论(0) 编辑 收藏 引用 所属分类:
JIT