Tomek wrote: > Hello > > I am asking about memory constraints in asm statements. > Suppose we have a class: > > class foo > { > public: > int table[2]; > }; > > and a function > > void do_something(foo & out_in, const foo & in) > { > __asm__ ( > "do something with out_in.table and in.table" > ); > } > > I am not sure how to correctly write constraints for out_in.table and > in.table. Assume that 'in' object is only for reading and 'out_in' is > for reading and writing. Following http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html > I was trying to write: > > void do_something(foo & out_in, const foo & in) > { > __asm__ ( > "some magic stuff" > : "+m"( ({ struct { int x[2]; } *p = (void *)out_in.table ; *p; }) ) > : other constraints > : .... > ); > } > > but it gave me: > test.cpp:50: error: invalid conversion from 'void*' to 'do_something(foo&, const foo&)::<anonymous struct>*' > (gcc 4.3.3 mingw) > > I changed a little the function and got: > > void do_something(foo & out_in, const foo & in) > { > struct temp { int t[2]; }; > temp * table1 = (temp*)out_in.table; > temp * table2 = (temp*)in.table; I don't think this is even legal C++. > > __asm__ ( > // out_in.table[0] = in.table[0] + in.table[1] + out_in.table[0]; > // out_in.table[1] = 0; > // (i386 asm) > > "movl (%%ecx), %%eax \n" > "addl 4(%%ecx), %%eax \n" > "addl %%eax, (%%ebx) \n" > "movl $0, 4(%%ebx) \n" > > : "+m" ( *table1 ) > : "b" (out_in.table), "c" (in.table), "m" ( *table2 ) > : "%eax", "cc" > ); > } > > And my question: is that a correct way to declare that out_in.table > is read and written by the asm statement (and in.table is only > for reading)? In this example don't I need to use 'volatile' with the > __asm__ keyword? I don't think so. I've discussed this with some other gcc developers, and consensus is that if you want to be safe, clobber memory and make the asm volatile. Like this: __asm__ volatile ( // out_in.table[0] = in.table[0] + in.table[1] + out_in.table[0]; // out_in.table[1] = 0; // (i386 asm) "movl (%2), %0 \n" "addl 4(%2), %1 \n" "addl %0, (%1) \n" "movl $0, 4(%1) \n" : "+r"(tmp) : "r" (out_in.table), "r" (in.table) : "cc", "memory" ); This does mean that your asm is effectively a memory barrier, but we can't see any way to avoid that. Andrew.