используя встроенный asm для написания цикла for с 2 сравнениями - PullRequest
1 голос
/ 12 мая 2010

Я хочу преобразовать цикл 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
    }
}

Ответы [ 3 ]

3 голосов
/ 12 мая 2010

Самый быстрый и простой способ начать работу по решению проблемы такого рода - сначала написать код на C или C ++ в максимально простой форме, а затем использовать компилятор C / C ++ для генерации asm. Затем вы можете использовать этот сгенерированный asm в качестве шаблона для вашего собственного кода asm. С правильным компилятором, таким как gcc, вы бы использовали gcc -S для этого. Я почти уверен, что Visual Studio имеет подобную опцию, скрытую где-то в ее графическом интерфейсе (очевидно, переключатель командной строки - /Fa).

1 голос
/ 12 мая 2010

Я не буду писать здесь asm, но вы должны исследовать три вещи:

  • хранить все в регистрах

  • не пересчитывайте a ^ 2 и b ^ 2 для ^ 2-b ^ 2, если вы уже вычислили их для a ^ 2 + b ^ 2

  • попытаться найти условие, которое позволяет установить n на N без итерации

0 голосов
/ 12 мая 2010

Цикл 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:
...