GCC内联汇编器输出问题

时间:2011-07-10 11:05:46

标签: gcc assembly

我试图通过移位和添加来增加汇编程序,并从以下代码中获得最奇怪的输出。如果int main中的最后两个函数调用被注释掉,我得到一个正常的结果,否则我得到第一次调用的正常结果和第二次和第三次的两次垃圾结果?

#include <iostream>

using namespace std;

int times_ten(int multiply_by_ten)
{
    int multiplied_by_ten = 0;
    //this multiplies by 10
    __asm__("shld   %%eax,%1;"
                  "movl %%eax,%%ebx;"
                  "shld  %%eax,%1;"
                  "shld  %%eax,%1;"
                  "addl  %%ebx,%%eax;"
                  : "=r" (multiplied_by_ten)
                  : "a" (multiply_by_ten)
    );

    return multiplied_by_ten;
}
int times_hundred(int multiply_by_hundred)
{
    int multiplied_by_hundred = 0;
    //this multiplies by 100
    __asm__("shld   %%eax,%1;"
                  "shld   %%eax,%1;"
                  "movl %%eax,%%ebx;"
                  "shld  %%eax,%1;"
                  "shld  %%eax,%1;"
                  "shld  %%eax,%1;"
                  "movl %%eax,%%edx;"
                  "shld  %%eax,%1;"
                  "addl  %%ebx,%%eax;"
                  "addl  %%edx,%%eax;"
                  : "=r" (multiplied_by_hundred)
                  : "a" (multiply_by_hundred)

    );

    return multiplied_by_hundred;
}
int main()
{
    cout<<times_hundred(1)<<endl;
    cout<<times_ten(1)<<endl;
    cout<<times_hundred(1)<<endl;

    return 0;
}

以下是clobber列表,但它不会编译。错误低于它。

#include <iostream>

using namespace std;

int times_ten(int multiply_by_ten)
{
    int multiplied_by_ten = 0;
    //this multiplies by 10
    __asm__("shld   %%eax,%1;"
                  "movl %%eax,%%ebx;"
                  "shld  %%eax,%1;"
                  "shld  %%eax,%1;"
                  "addl  %%ebx,%%eax;"
                  : "=r" (multiplied_by_ten)
                  : "a" (multiply_by_ten)
                  : "%%eax", "%%ebx"
    );

    return multiplied_by_ten;
}
int times_hundred(int multiply_by_hundred)
{
    int multiplied_by_hundred = 0;
    //this multiplies by 100
    __asm__("shld   %%eax,%1;"
                  "shld   %%eax,%1;"
                  "movl %%eax,%%ebx;"
                  "shld  %%eax,%1;"
                  "shld  %%eax,%1;"
                  "shld  %%eax,%1;"
                  "movl %%eax,%%edx;"
                  "shld  %%eax,%1;"
                  "addl  %%ebx,%%eax;"
                  "addl  %%edx,%%eax;"
                  : "=r" (multiplied_by_hundred)
                  : "a" (multiply_by_hundred)
                  : "%%eax", "%%ebx", "%%edx"
    );

    return multiplied_by_hundred;
}
int main()
{
    cout<<times_hundred(1)<<endl;
    cout<<times_ten(1)<<endl;
    cout<<times_hundred(1)<<endl;

    return 0;
}

|In function 'int times_ten(int)':|
error: unknown register name '%%ebx' in 'asm'|
error: unknown register name '%%eax' in 'asm'|
In function 'int times_hundred(int)':|
error: unknown register name '%%edx' in 'asm'|
error: unknown register name '%%ebx' in 'asm'|
error: unknown register name '%%eax' in 'asm'|
In function 'int main()':|
error: unknown register name '%%edx' in 'asm'|
error: unknown register name '%%ebx' in 'asm'|
error: unknown register name '%%eax' in 'asm'|
error: unknown register name '%%ebx' in 'asm'|
error: unknown register name '%%eax' in 'asm'|
error: unknown register name '%%edx' in 'asm'|
error: unknown register name '%%ebx' in 'asm'|
error: unknown register name '%%eax' in 'asm'|
||=== Build finished: 13 errors, 0 warnings ===|

2 个答案:

答案 0 :(得分:1)

修复%% clobber问题后,更改输出寄存器:

...
"addl  %%edx,%%eax;"
              : "=a" (multiplied_by_hundred)
              : "a" (multiply_by_hundred)
              : "%eax", "%ebx", "%edx"

从“= r”到“= a”。 编辑: 这适用于clang,但不适用于gcc。遗憾。

答案 1 :(得分:0)

此代码现在有效。

#include <iostream> 

using namespace std; 

int times_ten(int multiply_by_ten) 
{ 
         int multiplied_by_ten = 0; 
         //this multiplies by 10 
         __asm__("shl   $1, %%eax;" 
                                   "movl %%eax,%%ebx;" 
                                   "shl  $2, %%eax;" 
                                   "addl  %%ebx,%%eax;" 
                                   : "=a" (multiplied_by_ten) 
                                   : "0" (multiply_by_ten) : "%ebx" 
         ); 

         return multiplied_by_ten; 
} 
int times_hundred(int multiply_by_hundred) 
{ 
         int multiplied_by_hundred = 0; 
         //this multiplies by 100 
         __asm__("shl   $2, %%eax;" 
                                   "movl %%eax,%%ebx;" 
                                   "shl  $3, %%eax;" 
                                   "movl %%eax,%%edx;" 
                                   "shl  $1, %%eax;" 
                                   "addl  %%ebx,%%eax;" 
                                   "addl  %%edx,%%eax;" 
                                   : "=a" (multiplied_by_hundred) 
                                   : "0" (multiply_by_hundred) : "%ebx","%edx" 

         ); 

         return multiplied_by_hundred; 
} 
int main() 
{ 
         cout<<times_hundred(1)<<endl; 
         cout<<times_ten(1)<<endl; 
         cout<<times_hundred(1)<<endl; 

     return 0; 
}