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