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
>

Reply via email to