GCC inline assembler output problems

Cedric Roux cedric.roux@acri-st.fr
Mon Jul 11 08:00:00 GMT 2011


On 07/10/2011 03:10 PM, cryptocat wrote:
>
> I'm trying to multiply in assembler by shifting and adding and I get the
> weirdest output from the following code. If the last two function calls in
> the int main are commented out I get a normal result but otherwise I get a
> normal result for the first call and two garbage results for the second and
> third?
>
>
>      #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;
>      }
>
> The following has the clobber list but it wont compile. the errors are below
> it.
>
>      #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 ===|
>

that works here for me.
Might not be correct, I don't put the condition register in
the clobber list, and maybe other problems too which I am not
aware of...
HTH.

#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;
}



More information about the Gcc-help mailing list