Чтение / запись битов в памяти - PullRequest
3 голосов
/ 06 марта 2011

Допустим, у меня есть void* адрес памяти, и мне нужно распечатать биты, расположенные в этом адресе памяти.Как я могу это сделать?

В моей памяти процессора адреса 32 бита, как и значения памяти, также int 32 бита.Поэтому я подумал сделать это:

unsigned int value = *memory_address;

и затем с помощью простой арифметики (некоторые операции mod и div) получить биты значения, сохраненного в memory_address.

Например, value mod 2 выдаст последний бит этого значения и так далее.Но из того, что я могу сказать (я ожидал разные биты), это не работает.Есть идеи почему?

Кроме того, кто-нибудь знает о готовом исходном коде C, который «делает» это, читает / записывает биты из памяти?

Ответы [ 6 ]

7 голосов
/ 06 марта 2011

Сдвиг значения по одному для каждого бита и or его с 1

unsigned int value = *((unsigned int*)memory_address);
for( int i = 0; i < 32; i++)
{
    printf("%d ", value >> i & 1);
}

Вы также можете сделать это с помощью математических операторов.Вы должны получить значение бита (2 в степени индекса бита) и вычесть это значение на каждой итерации, чтобы убедиться, что модуль не возвращает значения, которые мы видели ранее:

for( int i = 0; i < 32; i++)
{ 
    int bit_value = (int)pow(2,i + 1);
    int num_bit_value = value % bit_value; 
    printf("%d ", num_bit_value ? 1 : 0  );
    value -= num_bit_value;
}
4 голосов
/ 06 марта 2011
int main() {

  int a = 0xFFFF;

  void * v = &a; // v points to a

  int * aPtr = (int *) v; // aPtr also points to a

  int b = *aPtr; // b gets the value aPtr points to, aka a or 0xFFFF

  int aBit = (b >> 3) & 1; // aBit now contains bit 3 of the original a value

  // toggle the bit
  if (aBit) {
    b &= ~(1 << 3); // set bit 3 to 0
  } else {
    b |= (1 << 3); // set bit 3 to 1
  }

  *aPtr = b; // update original a
}
2 голосов
/ 06 марта 2011

Мне было проще думать о памяти как о непрерывной строке символов, а не о пустом указателе. Таким образом, вы можете адресовать столько бит, сколько хотите.

Вот как я это сделал.

unsigned char
get_bit(char *array, int bit)
{
        int byte, k;
        byte = bit/8;
        k = 7 - bit % 8;
        return array[byte] & (1 << k);
}


void
set_bit(char *array, int bit, unsigned char value)
{
        int byte, k;
        byte = bit/8;
        k = 7 - bit % 8;
        if (value)
                array[byte] |= (1 << k);
        else
                array[byte] &= ~(1 << k);
}
0 голосов
/ 14 мая 2014

Универсальное решение для печати байтов и битов.

void dump_data(const void *object, size_t size)
{
  int i;
  printf("[ \n");
  for(i = 0; i < size; i++)
  {
    if (i%4 ==0)
    {
      printf("@%02X",&((const unsigned char *) object)[i]);
      printf("[ ");
    }
    printf("%02x ", ((const unsigned char *) object)[i] & 0xff);
    if ((i+1)%4 == 0)
      printf("]\n");
  }
  printf("]\n");

  printf("BINARY FORMAT\n");
  for (i = 0; i < size; i++)
  {
    printf("@%02X",&((const unsigned char *) object)[i]);
    printf("[ ");
    unsigned char value = (((unsigned char*)object)[i]);
    for(int j=0; j<8; j++)
      printf("%d ", (value & (0x80 >> j)) ? 1 : 0); // right shifting the value will print bits in reverse.
    printf("]\n");
  }
}
0 голосов
/ 06 марта 2011
bool getBit(void* data,int bit){ return ((*((int*)data)) & 1<<bit); }

void setBit(void* data,int bit,bool set){ if(set){ (*((int*)data)) |= 1<<bit; }else{ (*((int*)data)) &= ~(1<<bit);  } }

для простого использования

0 голосов
/ 06 марта 2011

Как насчет:

bool isBit4Set = ((*someAddress) & 0x8 != 0);
(*someAddress) |= 0x8;   // Set bit 4
...