|
|
|
|
|
|
|
《软件调试》答疑
帖子发起人: whislter 发起时间: 2008-10-16 17:56 下午 回复: 3
|
帖子排序:
|
|
|
|
2008-10-16, 17:56 下午
|
whislter
注册: 2008-10-07
发 贴: 3
|
|
|
第三章的fault演示小程序,VS2008 SP1下出现了问题——异常总是消除不掉,导致程序不断循环。看了下下载的bin里用VC6编译的,是不是较高版本的VC都有这个问题??发现是编译器在idiv指令上使用了寄存器,禁用编译器优化并且为除数加了volatile 都没用。直接修改生成的二进制文件后正常了。
修改前: /*1291078*/ mov ecx, dword ptr [ebp-1C] /*129107B*/ cdq /*129107C*/ idiv ecx
修改后: /*1291078*/ cdq /*1291079*/ idiv dword ptr [ebp-1C] /*129107C*/ nop /*129107D*/ nop
有没有什么办法让编译器不要把除数放到寄存器里?
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-10-16, 20:55 下午
|
格蠹老雷
注册: 2005-12-19
发 贴: 1,303
|
|
|
可以使用嵌入式汇编,改成下面的样子:
// nResult=nDividend / nDivisor; __asm{ mov eax, nDividend cdq idiv nDivisor mov nResult, eax };
我在VS2005上测试了一下是可以的。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2008-10-16, 22:24 下午
|
whislter
注册: 2008-10-07
发 贴: 3
|
|
|
谢谢张老师!
同样是改汇编,我第一反应居然没想到嵌入式汇编。。。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2009-06-14, 12:08 下午
|
笨笨
注册: 2009-06-14
发 贴: 3
|
|
|
关于这个问题
我想请教一下为什么把nDivisor 定义为volatile int nDivisor=0;依然会失败?
volatile是告诉cl该变量可能会以cl不知道的方式被改变,所以对该变量的访问不要做优化,要老老实实地按照programmer的指示去访问相应的memory.
编译,链接完成后,volatile已经体现在binary code中了,从binary中可以看到,对nDivisor的访问确实都没有被优化掉.
volatile是语言层面的keyword,它作用的对象是c/c++中的语句(sentence),是语句级的.
而本例乃异常(exception),是指令(instruction)级的,所以volatile起不了作用,只能用嵌入汇编.
请问我的理解对不?
ps:对于IA-32,有没有指令级的,作用与volatile相近的指令或compiler directive?
谢谢
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
高端调试 » 图书 » 《软件调试》答疑 » Re: 关于第三章Fault演示程序的疑问
|
|
|
|
|
|