--- Andrew Haley <[EMAIL PROTECTED]> wrote: > Etienne Lorrain writes: > > > The correct version is I think, > > > > > > void longcpy(long* _dst, long* _src, unsigned _numwords) > > > { > > > asm volatile ( > > > "cld \n\t" > > > "rep \n\t" > > > "movsl \n\t" > > > // Outputs (read/write) > > > : "=S" (_src), "=D" (_dst), "=c" (_numwords) > > > // Inputs - specify same registers as outputs > > > : "0" (_src), "1" (_dst), "2" (_numwords) > > > // Clobbers: direction flag, so "cc", and "memory" > > > : "cc", "memory" > > > ); > > > } > > > > I did not re-check with GCC-4.1.1, but I noticed problems with this > > kind of "memory" clobber: when the source you are copying from is > > not in memory but (is a structure) in the stack. I have to say that > > I tend to use a form without "volatile" after the asm (one of the > > result has to be used then). > > > > The usual symtom is that the memcopy is done, but the *content* of the > > source structure is not updated *before* the memcopy: nothing in your > > asm says that the content of your pointer has to be up-to-date. > > > > The "memory" says that main memory will be changed, not that it will be > > used, and if you are memcopy-ing from a structure in stack - for instance > > a structure which fit in a register - you may have problems. > > Why, exactly? the structure has its address taken, and therefore at > the point at which the asm is invoked it'll be in memory.
Well, first I am not sure it is still happening with GCC-4.1.1, and two I never got a reasonnable test case else you would have seen a bug report. The last time I noticed it was when I had to modify my file xms.h from: extern inline unsigned short _XMS_move_memory (farptr entrypoint, XMS_EMM *emm_struct, unsigned char *error) { unsigned short status; asm volatile (" lcallw *%a4 # XMS entry point, _XMS_move_memory " : "=a" (status), "=b" (*error) : "a" (0x0B00), "S" (emm_struct) /* %ds:%si */, "pr" (&entrypoint) ); if (status == 0x0001) return 0; /* OK */ else return 1; /* failed */ } to: extern inline unsigned short _XMS_move_memory (farptr entrypoint, XMS_EMM *emm_struct, unsigned char *error) { unsigned short status; asm volatile (" lcallw *%a4 # XMS entry point, _XMS_move_memory " : "=a" (status), "=b" (*error) : "a" (0x0B00), "S" (emm_struct) /* %ds:%si */, "pr" (&entrypoint), "m" (*emm_struct) ); if (status == 0x0001) return 0; /* OK */ else return 1; /* failed */ } With the first version Gujin (at sourceforge) does not work, with the second it does work - that function is inline in another big function so the assembler is not easy to read. emm_struct is a resonnably complex structure in the stack. I had to do this in few other include files with "m"(*ptr) or "X"(*ptr) for the same project in v1.4. > For sure, > if you fail to use volatile the compiler may decide that the asm can > be deleted. So use volatile: that's what it's for. I do not want the asm to be deleted when it is used, but in some case the compiler sees that I am not using the result and so I want GCC to delete the asm. Consider: inline void longcpy(long* _dst, long* _src, unsigned _numwords); inline void fct (long array[3], int doit) { long safe_copy[3]; longcpy(safe_copy, array, 3); if (!doit) return; /* safe_copy not used at all, remove the variable and the asm() */ ....; } void fct2(void) { fct (x, 0); } > If the compiler fails to write a struct to memory before the asm is > executed, that's a bug in the compiler. It you just said GCC that the pointer is read I am not sure it is assuming that the content of this pointer is read - I may be wrong. Etienne. __________________________________________________ Do You Yahoo!? En finir avec le spam? Yahoo! Mail vous offre la meilleure protection possible contre les messages non sollicités http://mail.yahoo.fr Yahoo! Mail