《Windows 用户态程序高效排错》市场价元 特价元 购买>> 读懂机器的语言汇编CPU执行指令的最小单元 需要用汇编来排错的常见情况 汇编是CPU执行指令的最小单元下面一些情况下汇编级别的分析通常是必要的 阅读代码看不出问题但是跑出来的结果就是不对怀疑编译器甚至CPU有毛病 没有源代码可以阅读比如调用某一个API的时候出问题没有Windows的源代码那就看汇编 当程序崩溃访问违例的时候调试器里看到的直接信息就是汇编 调试中涉及的汇编知识分为两部分 寄存器的运算对内存地址的寻址和读写这部分是跟CPU本身相关的 函数调用时候堆栈的变化局部变量全局变量的定位虚函数的调用这部分是跟编译器相关的 案例分析用汇编读懂VC编译器的优化 问题描述 客户在开发一个性能敏感的程序想知道VC编译器对下面这段代码的优化做得怎么样 int hgt=; int wid=; for (i=; i<hgt; i++) for (j=; j<wid; j++) A[i*wid+j] = exp((i*i+j*j)); 最直接的方法就是查看编译器生成的汇编代码分析有兴趣的话先自己调试一下看看跟我的分析是否一样 这段代码涉及到的优化有 i*i在每次内循环中是不变化的所以只需要在外循环里面重新计算编译器把外循环计算好的i*i放到ebx寄存器中内循环直接使用 对A[i*wid+j]寻址的时候在内循环里面变化的只有j而且每次j都是增加由于A是整型数组所以每次寻址的变化就是增加*sizeof (int)就是编译器把i*wid+j的结果放到了EDI中在内循环中每次add edi来实现了这个优化 对于中间变量编译器都是保存在寄存器中并没有读写内存 如果这段汇编让你手动来写你能做得比编译器更好一点吗? 案例分析VC 编译器的bugdebug模式正常release模式会崩溃 不要迷信编译器没有bug如果你在VS中测试下面的代码会发现在release mode下面程序会崩溃或者异常但是在debug mode下工作正常 程序中除了cout和printf外没有牵涉到系统相关的API所有的操作都是寄存器和内存上的操作所以不会是环境或者系统因素导致的可能性是代码错误(比如边界问题)或者编译器有问题 检查代码后没有发现异常同时如果调整一下std::transform的位置在for loop后面调用的话问题就不会发生 问题发生的情况跟编译模式相关 [] [] [] |