3

假设我有一个void*内存地址,我需要打印位于该内存地址中的位。我怎样才能做到这一点?

在我的处理器中,内存地址和内存值一样是 32 位,int 也是 32 位。所以我想到了这样做:

unsigned int value = *memory_address;

然后通过简单的算术(一些moddiv操作)来获取保存在memory_address.

例如value mod 2将给出这个值的最后一位等等。但据我所知(我期待不同的位)它不起作用。任何想法为什么?

此外,是否有人知道“这样做”的现成 C 源代码,从内存中读取/写入位?

4

6 回答 6

7

将每个位的值移1,然后移or1

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;
}
于 2011-03-06T01:41:14.427 回答
4
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
}
于 2011-03-06T01:36:22.540 回答
2

我发现将内存视为连续的字符串而不是空指针更容易。这样,您可以根据需要寻址任意数量的位。

这是我的做法。

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);
}
于 2011-03-06T01:43:11.927 回答
0

打印字节和位的通用解决方案。

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");
  }
}
于 2014-05-14T08:43:51.287 回答
0

怎么样:

bool isBit4Set = ((*someAddress) & 0x8 != 0);
(*someAddress) |= 0x8;   // Set bit 4
于 2011-03-06T01:34:25.803 回答
0
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);  } }

简单使用

于 2011-03-06T01:41:51.710 回答