问题: 在x64 Release下出现一个奇怪的bug,代码优化后一个浮点乘法运算出错了,例如1.0 × 1000 居然为 0。
分析:反汇编跟踪发现原来是寄存器的值传入有问题,本该传1000.0,结果传的是0.0。所用寄存器是xmm12,为什么会出现这个问题呢,发现是因为前面调用了
libmpeg2的函数修改了xmm寄存器的值。根据windows x64调用约定,函数调用在使用xmm6-xmm15寄存器之前/之后,要保存/恢复xmm寄存器。
libmpeg2库已经不更新了,所以只能在调用库函数之前和之后处理xmm寄存器的保存和恢复。
方案:x64已经不支持直接的内联汇编了,只能通过写汇编文件的方式来实现函数调用了。
首先,需写一个汇编文件,里面包括两个函数,一个是保存xmm寄存器,另一个是恢复xmm寄存器,参数传递是通过RCX,这个可以参考调用约定。
然后,设置工程,需先右键该工程,选择“生成自定义”选项,在弹出的对话框中选择编译器,如下图所以,此处使用的是yasm编译器
最后,添加该asm文件到工程中,右键该asm文件,在弹出的对话框中简单配置下,如下图所示
用extern声明asm中函数,在源文件中调用即可。
注意c语言中不能在函数中间定义变量。
x64调用约定参考:http://msdn.microsoft.com/zh-cn/library/ms235286%28v=vs.90%29.aspx