CMPXCHG16B correct?

后端 未结 5 711
粉色の甜心
粉色の甜心 2021-02-08 17:34

This doesn\'t exactly seem to be right although I am unsure why. Advice would be great as the documentation for CMPXCHG16B is pretty minimal (I don\'t own any intel manuals...)<

5条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-02-08 18:12

    I got it compiling for g++ with a slight change (removing oword ptr in cmpxchg16b instruction). But it doesn't seem to overwrite the memory as required though I may be wrong. [See update] Code is given below followed by output.

    #include 
    #include 
    
    namespace types
    {
      struct uint128_t
      {
        uint64_t lo;
        uint64_t hi;
      }
      __attribute__ (( __aligned__( 16 ) ));
     }
    
     template< class T > inline bool cas( volatile T * src, T cmp, T with );
    
     template<> inline bool cas( volatile types::uint128_t * src, types::uint128_t cmp,  types::uint128_t with )
     {
       bool result;
       __asm__ __volatile__
       (
        "lock cmpxchg16b %1\n\t"
        "setz %0"
        : "=q" ( result )
        , "+m" ( *src )
        , "+d" ( cmp.hi )
        , "+a" ( cmp.lo )
        : "c" ( with.hi )
        , "b" ( with.lo )
        : "cc"
       );
       return result;
    }
    
    void print_dlong(char* address) {
    
      char* byte_array = address;
      int i = 0;
      while (i < 4) {
         printf("%02X",(int)byte_array[i]);
         i++;
      }
    
      printf("\n");
      printf("\n");
    
    }
    
    int main()
    {
      using namespace types;
      uint128_t test = { 0xdecafbad, 0xfeedbeef };
      uint128_t cmp = test;
      uint128_t with = { 0x55555555, 0xaaaaaaaa };
    
      print_dlong((char*)&test);
      bool result = cas( & test, cmp, with );
      print_dlong((char*)&test);
    
      return result;
    }
    

    Output

    FFFFFFADFFFFFFFBFFFFFFCAFFFFFFDE
    
    
    55555555
    

    Not sure the output makes sense to me. I was expecting the before value to be something like 00000000decafbad00000feedbeef according to struct definition. But bytes seem to be spread out within words. Is that due to aligned directive? Btw the CAS operation seem to return the correct return value though. Any help in deciphering this?

    Update : I just did some debugging with memory inspection with gdb. There the correct values are shown there. So I guess this must be a problem with my print_dlong procedure. Feel free to correct it. I am leaving this reply as it is to be corrected, since a corrected version of this would be instructive of the cas operation with printed results.

提交回复
热议问题