Re: GCC inline assembler output problems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux