On Sat, Aug 12, 2017 at 9:21 PM, David Wohlferd <d...@limegreensocks.com> wrote: > Environment: > gcc 6.1 > compiling for 64bit i386 > optimizations: -O2 > > Consider this simple bit of code (from > https://stackoverflow.com/a/45656087/2189500): > > #include <stdio.h> > > int getStringLength(const char *pStr){ > > int len; > > __asm__ ( > "repne scasb\n\t" > "not %%ecx\n\t" > "dec %%ecx" > :"=c" (len), "+D"(pStr) > :"c"(-1), "a"(0) > ); > > return len; > } > > int main() > { > char buff[50] = "hello world"; > int a = getStringLength(buff); > printf("%s: %d\n", buff, a); > } > > This code works as expected and prints out 11. Yay. > > However, if you add "buff[4] = 0;" before the call to getStringLength, it > STILL prints out 11 (when optimizations are enabled), when it should print > 4. > > I would expect this kind of behavior if the asm were in 'main.' But it has > always been my understanding that function calls performed an implicit > memory clobber. The fact that this clobber goes away during inlining means > that code can stop working any time the compiler makes a different decision > about whether or not to inline a function. Ouch. > > And before somebody asks: Adding "+m"(pStr) does not help.
But does adding: "+m"(*pStr) Help? "+m"(pStr) Just says pStr variable changes, not what it points to. Thanks, Andrew Pinski > > The result is that (apparently) you can NEVER safely pass a buffer pointer > to inline asm without using the memory clobber. If this is true, I don't > believe it is widely known. > > Given how 'heavy' memory clobbers are, I would hope that only pointers that > have 'escaped' the function would get flushed before a function call. But > not flushing *anything* seems very bad. > > dw >