
我最近使用了/FAsu Visual C ++编译器选项来输出特别长的成员函数定义的源代码集合。 在汇编输出中,在堆栈框架设置完成后,会有一个调用神秘的_chkstk()函数。
_chkstk()上的MSDN页面没有解释调用这个函数的原因。 我也看到堆栈溢出问题在堆栈上分配一个页面大小的缓冲区会损坏内存? ,但我不明白OP和接受的答案是在说什么。
_chkstk() CRT函数的目的是什么? 它有什么作用?
如何从一个batch file中的另一个batch file从不同的目录启动一个exe文件?
获取调用堆栈的大小
在窗口上使用参数调用gnuplot脚本不起作用
为什么malloc / new捕获callstack?
python subprocess.call参数的问题
从程序集调用windows API,但没有硬编码地址
在没有堆栈的情况下在linux上进行系统调用
在windows关机调用WCF方法有时失败
如何调用C的extern函数并得到返回结构?
为什么我的IF比较 *** 作失败?
在使用时,为您的线程添加额外的windows页面。 在堆栈的最后,有一个防护页映射为不可访问的内存 – 如果程序访问它(因为它试图使用比当前映射更多的堆栈),则存在访问冲突。 *** 作系统发现故障,将堆栈的另一个页面映射到旧守卫页面的相同地址,创建一个新的守卫页面,并从导致违规的指令中恢复。
如果一个函数有多个局部变量页面,那么它访问的第一个地址可能会超过当前堆栈的一个页面。 因此,它会错过守护页,并触发 *** 作系统没有意识到的访问冲突,因为需要更多的堆栈。 如果所需要的堆栈总量特别巨大,甚至可能超出守卫页面,超出分配给堆栈的虚拟地址空间的末端,并进入实际用于其他事情的内存。
所以, _chkstk确保有足够的空间用于局部变量。 你可以想象它是通过以页面大小的间隔触摸局部变量的内存,按照升序来确保它不会错过保护页(所谓的“堆栈探测”)。 我不知道它是否真的这样做,但是,可能需要更直接的路线,并指示 *** 作系统映射一定的堆栈。 无论哪种方式,如果所需的总数大于可用于堆栈的虚拟地址空间,则 *** 作系统可以抱怨它,而不是做一些未定义的事情。
我查看了__chkstk的代码,它每隔一页做一次重复的堆栈探测。 所以这样就不需要对 *** 作系统进行任何调用。 rax的参数是要添加的数据的大小。 它确保目标地址(当前rsp – rax )是可访问的。 如果rax > rsp ,则为地址0执行此 *** 作。作为一个有趣的快捷方式,它首先将地址与映射的当前最低页面gs:[10h]进行比较; 如果目标地址> =这个,那么它什么都不做。
顺便说一句,对于至少64位的代码,它是拼写有两个下划线: __chkstk__ 。
总结以上是内存溢出为你收集整理的_chkstk()函数的目的是什么?全部内容,希望文章能够帮你解决_chkstk()函数的目的是什么?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)