1

我在 MSVC 上学习 x64 汇编。x64 代码中不允许内联汇编。我在一个单独的文件中写了一个非常简单的浮点函数:

.data
TWO_DOUBLE real8 2.0

.code
mul2 proc
    movsd xmm1, TWO_DOUBLE
    mulsd xmm0, xmm1
    ret 
mul2 endp

然后我从 C++ 调用我的函数:

extern "C" double mul2(double x);

int main()
{
    double d2 = mul2(1.0);
}

在发布模式下编译,/O2优化并/LTCG启用,我的反汇编可执行文件如下所示:

<addr> movsd  xmm0, mmword ptr [__real@3ff0000000000000 (013F9F21A8h)]  
<addr> call   mul2 (013F9F1075h)

但是,如果我用 C++ 编写相同的函数,它会被转换为一条内联mulsd指令。

(实际上,我不得不返回结果main以避免使整个程序成为空操作,并随机化输入变量以防止编译器在编译时计算结果。)

对于希望通过手写汇编优化代码的程序员来说,这似乎是一个非常严重的缺陷。如果 MSVC 不能内联它,那么除非您在程序集中进行大量工作,否则函数调用开销可能不值得。

有没有办法让 MSVC 内联我缺少的手写程序集?

编辑:我知道使用堆栈的更复杂的汇编函数可能更难以内联,但是仅使用易失性寄存器的简单事情应该真的很容易......对吗?

4

1 回答 1

3

对于 WPO(整个程序优化)应用跨模块内联,调用和被调用模块必须使用/LTGC.

/LTGC生成的不是最终的二进制代码,而是包含中间语言 (CIL) 的特殊目标文件。由于您的程序集已经是机器代码,因此它不能参与 WPO,因此不能内联。

如果您想使用 SIMD 指令但仍要利用 WPO,则可以使用编译器内在函数而不是汇编。例如,mulsd对应于_mm_mul_sd

于 2014-08-26T18:03:18.183 回答