1

我想将以下代码中的 for 循环转换为程序集,但我不知道如何开始。将不胜感激如何做到这一点以及它为什么起作用的解释。

我正在使用 VS2010,C++,为 x86 编写。代码如下:

for (n = 0; norm2 < 4.0 && n < N; ++n) 
{
    __asm{
    ///a*a - b*b + x
        fld a // a
        fmul st(0), st(0) // aa
        fld b // b aa
        fmul st(0), st(0) // bb aa
        fsub // (aa-bb) // st(0) - st(1)
        fld x // x (aa-bb)
        fadd // (aa-bb+x)

    /// 2.0*a*b + y;
        fld d // d (aa-bb+x)
        fld a // d a (aa-bb+x)
        fmul // ad (aa-bb+x)
        fld b // b ad (aa-bb+x)
        fmul // abd (aa-bb+x)
        fld y // y adb (aa-bb+x)
        fadd // b:(adb+y) a:(aa-bb+x)

        fld st(0) //b b:(adb+y) a:(aa-bb+x)
        fmul st(0), st(0) // bb b:(adb+y) a:(aa-bb+x)
        fld st(2) // a bb b:(adb+y) a:(aa-bb+x)
        fmul st(0), st(0) // aa bb b:(adb+y) a:(aa-bb+x)
        fadd // aa+bb b:(adb+y) a:(aa-bb+x)
        fstp norm2 // store aa+bb to norm2, st(0) is popped.
        fstp b
        fstp a
    }
}
4

3 回答 3

3

解决此类问题的最快速和最简单的方法是首先以尽可能简单的形式用 C 或 C++ 编写代码,然后使用 C/C++ 编译器生成 asm。然后,您可以使用这个生成的 asm 作为您自己的 asm 代码的模板。使用像 gcc 这样的适当编译器,您可以使用它gcc -S来执行此操作。我很确定 Visual Studio 在其 GUI 的某处隐藏了一个类似的选项(显然命令行开关是/Fa)。

于 2010-05-12T10:33:20.513 回答
1

我不会在这里写 asm,但你应该调查三件事:

  • 将所有内容保存在寄存器中

  • 当您已经为 a^2 + b^2 计算了 a^2 和 b^2 时,不要为 a^2-b^2 重新计算它们

  • 尝试找到一个允许将 n 设置为 N 而无需迭代的条件

于 2010-05-12T10:57:27.290 回答
0

for循环大致相同

if norm2>=4.0 then  // note condition inversed.
  goto end;
if 0<N then
  goto end; 
beginloop:

  <asm block>

   if norm2>=4.0 then  // note condition inversed.
     goto end;
   if (n<N)  then
     goto beginloop
end:
于 2010-05-12T10:34:11.650 回答