返回介绍

第 9 章 dcc - Benchsho.exe

发布于 2025-03-09 23:09:35 字数 14123 浏览 0 评论 0 收藏 0

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) 的使用而造成有三个额外的指令。

 mainPROC NEAR   
0000002FA55PUSHbp 
0010002FB8BECMOVbp,sp 
0020002FD83EC0ESUBsp,0Eh 
0030003008D46FCLEAax,[bp-4] 
00400030350PUSHax 
005000304B89401MOVax,194h 
00600030750PUSHax 
007000308E8E914CALLnear ptr scanf 
00800030B59POPcx 
00900030C59POPcx 
01000030DFF76FEPUSHword ptr [bp-2] 
011000310FF76FCPUSHword ptr [bp-4] 
012000313B89801MOVax,198h 
01300031650PUSHax 
014000317E8510CCALLnear ptr printf 
01500031A83C406ADDsp,6 
01600031D8D46F2LEAax,[bp-0Eh] 
01700032050PUSHax 
018000321B8B201MOVax,1B2h 
01900032450PUSHax 
020000325E8CC14CALLnear ptr scanf 
02100032859POPcx 
02200032959POPcx 
02300032A8D46F4LEAax,[bp-0Ch] 
02400032D50PUSHax 
02500032EB8B601MOVax,1B6h 
02600033150PUSHax 
027000332E8BF14CALLnear ptr scanf 
02800033559POPcx 
02900033659POPcx 
030000337C746FA0000MOVword ptr [bp-6],0 
03100033CC746F80100MOVword ptr [bp-8],1 
0330003BD8B56FAL1: MOVdx,[bp-6] 
0340003C08B46F8MOVax,[bp-8] 
0350003C33B56FECMPdx,[bp-2] 
0360003C67D03JGEL2 
038000344C746F60100L3: MOVword ptr [bp-0Ah],1 
0400003AF837EF628L4: CMPword ptr [bp-0Ah],28h 
0410003B37E96JLEL5 
0420003B58346F801ADDword ptr [bp-8],1 
0430003B98356FA00ADCword ptr [bp-6],0 
044  JMPL1;Synthetic inst
04500034B8B46F2L5: MOVax,[bp-0Eh] 
04600034E0346F4ADDax,[bp-0Ch] 
0470003510346F6ADDax,[bp-0Ah] 
0480003548946F2MOV[bp-0Eh],ax 
0490003578B46F2MOVax,[bp-0Eh] 
05000035AD1F8SARax,1 
05100035C8946F4MOV[bp-0Ch],ax 
05200035F8B46F4MOVax,[bp-0Ch] 
053000362BB0A00MOVbx,0Ah 
05400036599CWD  
055  MOVtmp,dx:ax;Synthetic inst
056000366F7FBIDIVbx 
057  MODbx;Synthetic inst
0580003688956F2MOV[bp-0Eh],dx 
05900036B8B46F4MOVax,[bp-0Ch] 
06000036E3B46F6CMPax,[bp-0Ah] 
0610003717505JNEL6 
062000373B80100MOVax,1 
06400037A8946F2L7: MOV[bp-0Eh],ax 
06500037D8B46F2MOVax,[bp-0Eh] 
0660003800B46F6ORax,[bp-0Ah] 
0670003838946F4MOV[bp-0Ch],ax 
0680003868B46F4MOVax,[bp-0Ch] 
069000389F7D8NEGax 
07000038B1BC0SBBax,ax 
07100038D40INCax 
07200038E8946F2MOV[bp-0Eh],ax 
0730003918B46F2MOVax,[bp-0Eh] 
0740003940346F6ADDax,[bp-0Ah] 
0750003978946F4MOV[bp-0Ch],ax 
07600039A8B46F4MOVax,[bp-0Ch] 
07700039D3B46F6CMPax,[bp-0Ah] 
0780003A07E05JLEL8 
0790003A2B80100MOVax,1 
0810003A98946F2L9: MOV[bp-0Eh],ax 
0820003ACFF46F6INCword ptr [bp-0Ah] 
083  JMPL4;Synthetic inst
0840003A733C0L8: XORax,ax 
085  JMPL9;Synthetic inst
08600037833C0L6: XORax,ax 
087  JMPL7;Synthetic inst
0880003CB7F08L2: JGL10 
0890003CD3B46FCCMPax,[bp-4] 
0900003D07703JAL10 
0920003D5FF76F2L10: PUSHword ptr [bp-0Eh] 
0930003D8B8BA01MOVax,1BAh 
0940003DB50PUSHax 
0950003DCE88C0BCALLnear ptr printf 
0960003DF59POPcx 
0970003E059POPcx 
0980003E18BE5MOVsp,bp 
0990003E35DPOPbp 
1000003E4C3RET  
 mainENDP   

图 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文