第 9 章 dcc - Benchsho.exe
9.7.4 Benchsho.exe
Benchsho 是来自 Plum-Hall 基准程序套装的一个程序,测试短整型数。该程序使用两个长整型变量反复经过循环,以及三个(短) 整型变量执行 1000 个运算。反汇编的程序在图 9-27 被显示,反编译的 C 程序在图 9-28,最初的 C 程序在图 9-29。该程序有下列调用图:
main scanf printf |
从该程序的反汇编可知,长整型变量位于栈上偏移-4 和-8 处,而整型变量位于偏移-14、-12、和-10 处。最后的 C 代码使用整型变量 loc6 保存一个布尔表达式的结果 (即,0 或 1) 而且把它赋给对应的变量。这个布尔变量是一个寄存器变量 (寄存器 ax) 而且可能被更进一步的控制流向图分析从代码中清除掉,类似于组合条件的结构化方法。
图 9-26: 布尔赋值的控制流向图
例如,如果满足下列条件,图 9-26 中的图(a) 能够被缩减为图(b):
1. 结点 1 是一个二路结点。
2. 结点 2 和结点 3 只有一个来自结点 1 的入边,而且通向一个共同的结点 4。
3. 结点 2 和结点 3 只有一个指令。这个指令分别地对一个寄存器赋值 0 和 1。
4. 结点 4 把结点 2 和结点 3 的寄存器赋给一个局部变量。在该程序中,该寄存器没有在重新定义之前再被使用。
因为该寄存器只被使用一次储存一个布尔表达式评估的中间结果,所以它被从把布尔表达式赋给目标变量的最后代码中清除掉。这个转换不仅去掉了有关的寄存器,而且也去掉了赋值给它的那两个结点 (即,在图 9-26 的图中结点 2 和结点 3)。
显然,图 9-28 的两个布尔赋值能够被转换成下列代码:
loc1 = (loc2 == loc3); /* other code */ loc1 = (loc2 > loc3); |
这会使最后的 C 程序成为最初的 C 程序的一个准确反编译。没有这个转换,所产生的 C 代码跟最初的 C 代码在功能上是等价的,而且在结构上跟反编译的图是等价的。因为一个布尔赋值的图天生是结构化的,如果不实现这个转换无论如何也不会生成非结构化的代码,不像组合条件的情况——它是天生非结构化的图被转换成结构化的图。
没有图的最优化,由 dcc 生成的最后的反编译代码产生 75.25%的中间指令数目缩减率,如图 9-30 所示。对于最初 C 代码的每个布尔赋值,由于一个临时局部变量 (在这个例子中是 loc6) 的使用而造成有三个额外的指令。
main | PROC NEAR | ||||
000 | 0002FA | 55 | PUSH | bp | |
001 | 0002FB | 8BEC | MOV | bp,sp | |
002 | 0002FD | 83EC0E | SUB | sp,0Eh | |
003 | 000300 | 8D46FC | LEA | ax,[bp-4] | |
004 | 000303 | 50 | PUSH | ax | |
005 | 000304 | B89401 | MOV | ax,194h | |
006 | 000307 | 50 | PUSH | ax | |
007 | 000308 | E8E914 | CALL | near ptr scanf | |
008 | 00030B | 59 | POP | cx | |
009 | 00030C | 59 | POP | cx | |
010 | 00030D | FF76FE | PUSH | word ptr [bp-2] | |
011 | 000310 | FF76FC | PUSH | word ptr [bp-4] | |
012 | 000313 | B89801 | MOV | ax,198h | |
013 | 000316 | 50 | PUSH | ax | |
014 | 000317 | E8510C | CALL | near ptr printf | |
015 | 00031A | 83C406 | ADD | sp,6 | |
016 | 00031D | 8D46F2 | LEA | ax,[bp-0Eh] | |
017 | 000320 | 50 | PUSH | ax | |
018 | 000321 | B8B201 | MOV | ax,1B2h | |
019 | 000324 | 50 | PUSH | ax | |
020 | 000325 | E8CC14 | CALL | near ptr scanf | |
021 | 000328 | 59 | POP | cx | |
022 | 000329 | 59 | POP | cx | |
023 | 00032A | 8D46F4 | LEA | ax,[bp-0Ch] | |
024 | 00032D | 50 | PUSH | ax | |
025 | 00032E | B8B601 | MOV | ax,1B6h | |
026 | 000331 | 50 | PUSH | ax | |
027 | 000332 | E8BF14 | CALL | near ptr scanf | |
028 | 000335 | 59 | POP | cx | |
029 | 000336 | 59 | POP | cx | |
030 | 000337 | C746FA0000 | MOV | word ptr [bp-6],0 | |
031 | 00033C | C746F80100 | MOV | word ptr [bp-8],1 | |
033 | 0003BD | 8B56FA | L1: MOV | dx,[bp-6] | |
034 | 0003C0 | 8B46F8 | MOV | ax,[bp-8] | |
035 | 0003C3 | 3B56FE | CMP | dx,[bp-2] | |
036 | 0003C6 | 7D03 | JGE | L2 | |
038 | 000344 | C746F60100 | L3: MOV | word ptr [bp-0Ah],1 | |
040 | 0003AF | 837EF628 | L4: CMP | word ptr [bp-0Ah],28h | |
041 | 0003B3 | 7E96 | JLE | L5 | |
042 | 0003B5 | 8346F801 | ADD | word ptr [bp-8],1 | |
043 | 0003B9 | 8356FA00 | ADC | word ptr [bp-6],0 | |
044 | JMP | L1 | ;Synthetic inst | ||
045 | 00034B | 8B46F2 | L5: MOV | ax,[bp-0Eh] | |
046 | 00034E | 0346F4 | ADD | ax,[bp-0Ch] | |
047 | 000351 | 0346F6 | ADD | ax,[bp-0Ah] | |
048 | 000354 | 8946F2 | MOV | [bp-0Eh],ax | |
049 | 000357 | 8B46F2 | MOV | ax,[bp-0Eh] | |
050 | 00035A | D1F8 | SAR | ax,1 | |
051 | 00035C | 8946F4 | MOV | [bp-0Ch],ax | |
052 | 00035F | 8B46F4 | MOV | ax,[bp-0Ch] | |
053 | 000362 | BB0A00 | MOV | bx,0Ah | |
054 | 000365 | 99 | CWD | ||
055 | MOV | tmp,dx:ax | ;Synthetic inst | ||
056 | 000366 | F7FB | IDIV | bx | |
057 | MOD | bx | ;Synthetic inst | ||
058 | 000368 | 8956F2 | MOV | [bp-0Eh],dx | |
059 | 00036B | 8B46F4 | MOV | ax,[bp-0Ch] | |
060 | 00036E | 3B46F6 | CMP | ax,[bp-0Ah] | |
061 | 000371 | 7505 | JNE | L6 | |
062 | 000373 | B80100 | MOV | ax,1 | |
064 | 00037A | 8946F2 | L7: MOV | [bp-0Eh],ax | |
065 | 00037D | 8B46F2 | MOV | ax,[bp-0Eh] | |
066 | 000380 | 0B46F6 | OR | ax,[bp-0Ah] | |
067 | 000383 | 8946F4 | MOV | [bp-0Ch],ax | |
068 | 000386 | 8B46F4 | MOV | ax,[bp-0Ch] | |
069 | 000389 | F7D8 | NEG | ax | |
070 | 00038B | 1BC0 | SBB | ax,ax | |
071 | 00038D | 40 | INC | ax | |
072 | 00038E | 8946F2 | MOV | [bp-0Eh],ax | |
073 | 000391 | 8B46F2 | MOV | ax,[bp-0Eh] | |
074 | 000394 | 0346F6 | ADD | ax,[bp-0Ah] | |
075 | 000397 | 8946F4 | MOV | [bp-0Ch],ax | |
076 | 00039A | 8B46F4 | MOV | ax,[bp-0Ch] | |
077 | 00039D | 3B46F6 | CMP | ax,[bp-0Ah] | |
078 | 0003A0 | 7E05 | JLE | L8 | |
079 | 0003A2 | B80100 | MOV | ax,1 | |
081 | 0003A9 | 8946F2 | L9: MOV | [bp-0Eh],ax | |
082 | 0003AC | FF46F6 | INC | word ptr [bp-0Ah] | |
083 | JMP | L4 | ;Synthetic inst | ||
084 | 0003A7 | 33C0 | L8: XOR | ax,ax | |
085 | JMP | L9 | ;Synthetic inst | ||
086 | 000378 | 33C0 | L6: XOR | ax,ax | |
087 | JMP | L7 | ;Synthetic inst | ||
088 | 0003CB | 7F08 | L2: JG | L10 | |
089 | 0003CD | 3B46FC | CMP | ax,[bp-4] | |
090 | 0003D0 | 7703 | JA | L10 | |
092 | 0003D5 | FF76F2 | L10: PUSH | word ptr [bp-0Eh] | |
093 | 0003D8 | B8BA01 | MOV | ax,1BAh | |
094 | 0003DB | 50 | PUSH | ax | |
095 | 0003DC | E88C0B | CALL | near ptr printf | |
096 | 0003DF | 59 | POP | cx | |
097 | 0003E0 | 59 | POP | cx | |
098 | 0003E1 | 8BE5 | MOV | sp,bp | |
099 | 0003E3 | 5D | POP | bp | |
100 | 0003E4 | C3 | RET | ||
main | ENDP |
图 9-27: Benchsho.a2
/* * Input file : benchsho.exe * File type : EXE */ #include "dcc.h" void main () /* Takes no parameters. * High-level language prologue code. */ { int loc1; int loc2; int loc3; long loc4; long loc5; int loc6; /* ax */ scanf ("%ld", &loc5); printf ("executing %ld iterations\n", loc5); scanf ("%ld", &loc1); scanf ("%ld", &loc2); loc4 = 1; while ((loc4 <= loc5)) { loc3 = 1; while ((loc3 <= 40)) { loc1 = ((loc1 + loc2) + loc3); loc2 = (loc1 >> 1); loc1 = (loc2 % 10); if (loc2 == loc3) { loc6 = 1; } else { loc6 = 0; } loc1 = loc6; loc2 = (loc1 | loc3); loc1 = !loc2; loc2 = (loc1 + loc3); if (loc2 > loc3) { loc6 = 1; } else { loc6 = 0; } loc1 = loc6; loc3 = (loc3 + 1); } loc4 = (loc4 + 1); } printf ("a=%d\n", loc1); } |
图 9-28: Benchsho.b
/* benchsho - benchmark for short integers * Thomas Plum, Plum Hall Inc, 609-927-3770 * If machine traps overflow, use an unsigned type * Let T be the execution time in milliseconds * Then average time per operator = T/major usec * (Because the inner loop has exactly 1000 operations) */ #define STOR_CL auto #define TYPE short #include <stdio.h> main (int ac, char *av[]) { STOR_CL TYPE a, b, c; long d, major; scanf ("%ld", &major); printf("executing %ld iterations\n", major); scanf ("%ld", &a); scanf ("%ld", &b); for (d = 1; d <= major; ++d) { /* inner loop executes 1000 selected operations */ for (c = 1; c <= 40; ++c) { a = a + b + c; b = a >> 1; a = b % 10; a = b == c; b = a | c; a = !b; b = a + c; a = b > c; } } printf("a=%d\n", a); } |
图 9-29: Benchsho.c
子程序 | 低级 | 高级 | % 缩减率 |
main | 101 | 25 | 75.25 |
合计 | 101 | 25 | 75.25 |
图 9-30: Benchsho 统计
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论