This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: GCC inline assembler output problems


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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]