This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

memcpy on register variables

Hi,
I have a small helper function which does the following:

  static void SetDelay( BYTE bBytes0_3, BYTE* pb, DWORD dw)
  { memcpy( pb, &dw, bBytes0_3+1); }

This fails (invoked with bBytes0_3= 0 - so only 1 byte to copy). If I look into the disassembly, the compiler is doing something very strange (Opt level 1, c++, compiler version V5.03.0.76):

dw is given to the function via r2, as usual.

Then the r0-r2 is pushed to stack. And r1 is pointing to the correct stack range where the r2 data is sitting. So far so nice.

But before the code jumps into memcpy, the stack is popped back (r1 still pointing to the r2 data range, but meanwhile this data range is over the top of the stack ...). Then inside memcpy the stack is pushed again, thereby overwriting the r2 data info ... so then this wrong byte is written to the target address.

Am I doing here something severely illegal / abnormal? Or should I somehow declare the variable "dw" as "non-register" / is there a simple way to do this?

Parents
  • That looks like real ugly code.

    I would immediately wonder what the compiler considers to be the lifetime of dw. It probably see's it as a simple value and therefore considers it safe to discard the temporary storage. Someone familiar with the standard could probably advise on the facts tho.

    Why not try to break it down a bit and let the compiler optimize it as it sees fit.

    static void SetDelay( BYTE bBytes0_3, BYTE* pb, DWORD dw)
    {
      DWORD CopyOfDw = dw;
      memcpy( pb, &CopyOfDw, bBytes0_3+1);
    }
    

Reply
  • That looks like real ugly code.

    I would immediately wonder what the compiler considers to be the lifetime of dw. It probably see's it as a simple value and therefore considers it safe to discard the temporary storage. Someone familiar with the standard could probably advise on the facts tho.

    Why not try to break it down a bit and let the compiler optimize it as it sees fit.

    static void SetDelay( BYTE bBytes0_3, BYTE* pb, DWORD dw)
    {
      DWORD CopyOfDw = dw;
      memcpy( pb, &CopyOfDw, bBytes0_3+1);
    }
    

Children
  • This I tried already. It runs into the same problem.

    I now ended up with using a for loop instead of the memcpy:

      static void SetDelay( BYTE bBytes0_3, BYTE* pb, DWORD dw)
      { BYTE* pb2= (BYTE*)&dw;
        for( int i= 0; i<= bBytes0_3; i++) *pb++= *pb2++; }
    
    

    This works.