看板Programming
标 题结构化指令的底层塑造法 (范例)
发信站枫桥驿站 (Wed Dec 15 04:38:47 2010)
转信站ptt!news.ntu!ctu-gate!news.nctu!newsfeed.nthu!news.cs.nthu!MapleBBS
内容范围: 程式编译器.
内容程度: 一般.
内容抽象: 实例.
内容精度: 实作.
这篇是使用我自己的一个小编译器产生的反组译结果. 你可以自行比较结构化
语法与机械指令转换间的差异.
总共有三个范例:
(A) 简单 IF/ELSE/ENDIF
(B) 巢套 IF..ENDIF
(C) FOR 结构
另外解释一下, 反组译後的机械指令不是x86 码, 或是其它种类的CPU.而是我
自行定义的运算机器.
「系统虚拟码」是前置处理器产生的初步结果. 然後编译器才转换成「实体」
的机械码. 最後的反组译结果是由机械码转换回来的. 已经看不出虚拟码或原始码
的格式. 但大体上还是可以猜猜看的.
我列出这一篇的原因是让游客能顺便看看转换前後的影响. 即使你不写编译器.
也能看出转换後的复杂度. 如果这是上百行到数千行的程式. 肯定你要分解出各个
「制式结构」段落和一般运算码, 就会很伤眼睛了.
你不需要去完全了解指令的意义. 只要看看转换前後变得有多大即可.
你可以从这个范例知道. 如果每次你要用到结构化指令的功能时, 如果还要「
手写」出这些「制式」指令. 你就没有哪麽大的程式生产量了! 而且, 除错与维护
也会变得困难许多. 看到这里, 你就能想像, 最早能将青菜萝卜煮成桌上佳肴的人
有多伟大了!
Tommy 99/12/15
(A) 简单 IF/ELSE/ENDIF
=*= 原始码 =*=
$IF f REM '假指令 $IF 参数: 旗标号码.'
fmt 'Do IF'
$ELSE
fmt 'Do ELSE'
$ENDIF
=*= 系统虚拟码 =*=
指令名 机械码 参数
[$IF] * (f) ,f
[fmt] 34 (S) ,Do IF
[$ELSE] *
[fmt] 34 (S) ,Do ELSE
[$ENDIF] *
[POut] 35
=*= 机械码 =*=
33 0 3 1 31 34 0 31 3 2 22 3 31 34 1 22 4 31 35
=*= 反组译码 =*=
Offset == Code ==
00000: Nif f
00002: Goto .IF_f.1
00004: Bgn
00005: Fmt 'Do IF'
00007: Bgn
00008: Goto .IF_f.1.
00010: Lab .IF_f.1
00012: Bgn
00013: Fmt 'Do ELSE'
00015: Lab .IF_f.1.
00017: Bgn
00018: POut
(B) 巢套 IF..ENDIF
=*= 原始码 =*=
$IF f REM '假指令 $IF 参数: 旗标号码.'
fmt 'Do IF'
$IF f2
fmt 'Do IF level 2'
$ELSE
fmt 'Do ELSE level 2'
$IF f3
fmt 'Do IF level 3'
$ELSE
fmt 'Do ELSE level 3'
$ENDIF
$ENDIF
$ELSE
fmt 'Do ELSE'
$ENDIF
=*= 系统虚拟码 =*=
指令名 机械码 参数
[$IF] * (f) ,f
[fmt] 34 (S) ,Do IF
[$IF] * (f) ,f2
[fmt] 34 (S) ,Do IF level 2
[$ELSE] *
[fmt] 34 (S) ,Do ELSE level 2
[$IF] * (f) ,f3
[fmt] 34 (S) ,Do IF level 3
[$ELSE] *
[fmt] 34 (S) ,Do ELSE level 3
[$ENDIF] *
[$ENDIF] *
[$ELSE] *
[fmt] 34 (S) ,Do ELSE
[$ENDIF] *
[POut] 35
=*= 机械码 =*=
33 0 3 1 31 34 0 33 2 3 3 31 34 1 31 3 4 22 5 31 34 2
33 6 3 7 31 34 3 31 3 8 22 9 31 34 4 22 10 31 22 11 31
31 3 12 22 13 31 34 5 22 14 31 35
=*= 反组译码 =*=
Offset == Code ==
00000: Nif f
00002: Goto .IF_f.1
00004: Bgn
00005: Fmt 'Do IF'
00007: Nif f2
00009: Goto .IF_f2.2
00011: Bgn
00012: Fmt 'Do IF level 2'
00014: Bgn
00015: Goto .IF_f2.2.
00017: Lab .IF_f2.2
00019: Bgn
00020: Fmt 'Do ELSE level 2'
00022: Nif f3
00024: Goto .IF_f3.3
00026: Bgn
00027: Fmt 'Do IF level 3'
00029: Bgn
00030: Goto .IF_f3.3.
00032: Lab .IF_f3.3
00034: Bgn
00035: Fmt 'Do ELSE level 3'
00037: Lab .IF_f3.3.
00039: Bgn
00040: Lab .IF_f2.2.
00042: Bgn
00043: Bgn
00044: Goto .IF_f.1.
00046: Lab .IF_f.1
00048: Bgn
00049: Fmt 'Do ELSE'
00051: Lab .IF_f.1.
00053: Bgn
00054: POut
(C) FOR 结构
=*= 原始码 =*=
$FOR mCnt 1 10 1 REM '假指令 $For 参数: 变数名, 初值, 终点值, 递增值.'
fmt '?m:mCnt'
pout
$NEXT mCnt
=*= 系统虚拟码 =*=
指令名 机械码 参数
[$FOR] 24 (vLLL) ,mCnt ,1 ,10 ,1
[fmt] 34 (S) ,?m:mCnt
[pout] 35
[$NEXT] 25 (v) ,mCnt
[POut] 35
=*= 机械码 =*=
91 1 33 2 3 3 31 114 4 109 3 22 5 117 0 4 3 6 31 34 1
35 91 8 31 114 9 115 5 116 31 3 10 22 11 32 12 35
=*= 反组译码 =*=
Offset == Code ==
00000: SetFF .f_FOR_mCnt.1
00002: Nif .f_FOR_mCnt.1
00004: Goto .FOR_mCnt.1.
00006: Bgn
00007: CntSw mCnt
00009: CntS 1
00011: Lab .FOR_mCnt.1
00013: CmpCnt > 10
00016: Goto .FOR_mCnt.1.
00018: Bgn
00019: Fmt '?m:mCnt'
00021: POut
00022: SetFF .f_FOR_mCnt.1
00024: Bgn
00025: CntSw mCnt
00027: CntDo 1
00029: CntSv
00030: Bgn
00031: Goto .FOR_mCnt.1
00033: Lab .FOR_mCnt.1.
00035: If .f_FOR_mCnt.1
00037: POut
--
※ Origin: 枫桥驿站<bbs.cs.nthu.edu.tw>
◆ From: tommy @ 125-232-132-134.dynamic.hinet.net