| 准确定制Windows应用程序堆栈大小
| | 初中计算机教研论文在编写windows应用程序时,我们是通过模块定义文件(.def)中的初中计算机教研论文stacksize语句来定义以字节为单位的初中计算机教研论文应用程序堆栈大小,以用于函数参数的中间存储。根据windows sdk手册的推荐,最小堆栈大小应为5120字节。事实上,这是一个比实际需求放宽了许多的推荐值。microsoft公司没有对如何准确设定这一参数提供有效方法。由于windows本身是一个多任务环境,可以同时运行多个应用程序,因此,我们对堆栈参数的选择会导致有限内存空间的浪费。在此,本文给出一种准确定制windows应用程序堆栈大小的方法,具体的实现方法如下。 根据andrew schulman在《未公开的windows核心技术》中提供的资料,在应用程序的实例句柄所指向的缺省数据段起始位置,windows定义了如下的instdata结构: typedef struct { word wmustbezero; //此参数必须为零 dword dw01dsssp; //保存当前的ss:sp指针; word plocalheap; //指向局部堆信息结构的近指针 word patomtable; //指向任务原子表的近指针 word pstacktop; //指向栈顶的近指针 word pstackmin; //当前使用的堆栈大小 word pstackbottom; //指向栈底的近指针 } instdata; 我们提供的方法的思路是,在应用程序被加载时,先在堆栈区的栈顶位置到当前sp之间填充固定字节(如0xaa)来进行初始化。在程序执行结束时,通过对堆栈区初始化值的改变情况来计算应用程序所使用的实际堆栈的大小。以上的工作主要依靠下面两个函数来完成。 1.堆栈初始化函数 void far pascal setstack(void) { byte near *npstacktop,near *npstackcurrent; npstacktop=((npinstdata)0x0000)→pstacktop; -asm mov npstackcurrent,sp; npstackcurrent-=2; while(npstacktop<npstackcurrent) *npstacktop++=0xaa; } 2.堆栈大小计算函数 word far pascal cacustack(void) { byte near *npstacktop,near *npstackbottom; npstacktop=((npinstdata)0x0000)→pstacktop; npstackbottom=((npinstdata)0x0000)→pstackbottom; while(*npstacktop=0xaa) npstacktop++; return((word)(npstackbottom-npstacktop)); } 在应用程序中调用以上两个函数以定制堆栈大小的方法如下例所 示: int pascal winmain(hinstance, hprevinstance, 1pcmdline, ncmdshow) handle hinstance; /*current instance*/ handle hprevinstance; /*previous instance*/ lpstr 1pcmdline; /*command line*/ int ncmdshow; /*show-window type (open/icon)*/ { char szechomsg[60]; msc msg; setstack (); if (!hprevinstance) /*other instances of app running?*/ if (!initapplication(hinstance)) /*initialize shared thi ngs*/ return (false); /*exit if unable to initialize*/ /*perform initializations that apply to a specific insta nce*/ if (!initinstance(hinstance,ncmdshow)) return (false); /*acquire and dispatch messages until a wm-quit message is received. */ while (getmessage(&msg, /*message structure*/ null, /*handle of window receiving the message*/ null, /*lowest message to examine*/ null)) /*highest message to examine*/ { translatemessage(&msg); /*translates virtual key codes*/ dispatchmessage(&msg); /*dispatches message to window*/ } wsprintf(szechomsg, actual stack size:%u\n\r,cacustack ()); outputdebugstring(szechomsg); return(msg.wparam); /*returns the value from postquitmes sage */ } 要注意的是,利用本文提供的方法来对具体程序进行堆栈大小的计算时,使用者应反复多次运行应用程序,并逐一执行程序中的不同功能,记录下每次退出程序所显示的实际堆栈大小,取其中的最大值,略放余量后回填到.def文件的stacksize语句中。
| | | |
|