了解转移和逻辑运算

时间:2013-06-29 07:59:09

标签: c bitwise-operators logical-operators

我正在尝试读取SD卡的“尺寸”。我所拥有的示例示例包含以下代码行:

unsigned char xdata *pchar; // Pointer to external mem space for FLASH Read function;
pchar += 9; // Size indicator is in the 9th byte of CSD (Card specific data) register;

 // Extract size indicator bits;
size = (unsigned int)((((*pchar) & 0x03) << 1) | (((*(pchar+1)) & 0x80) >> 7));

我无法理解在上面提到指标位的行中实际做了什么。有人可以帮我理解这个吗?

4 个答案:

答案 0 :(得分:4)

size由两个字节的位组成。一个字节位于pchar,另一个字节位于pchar + 1

(*pchar) & 0x03)取2个最低有效位(砍掉6个最重要的位)。 使用<< 1将此结果向左移一位。例如:

11011010 (& 0x03/00000011)==> 00000010 (<< 1)==> 00000100 (-----10-)

pchar + 1做了类似的事情。例如:

11110110 (& 0x80/10000000)==> 10000000 (>> 7)==> 00000001 (-------1)

然后将这两个值与|进行OR运算。所以在这个例子中你会得到:

00000100 | 00000001 = 00000101 (-----101)

但请注意,5个最高有效位始终为0(上面标有-),因为它们是& - ed away:

总而言之,第一个字节保存两位size,而第二个字节只保存一位。

答案 1 :(得分:3)

似乎SI的大小指示符由3位组成,其中*pchar包含最低两位(0x03)和*(pchar+1)中包含两个最高有效位的SI最高位(0x80)中SI的最低有效位。

答案 2 :(得分:1)

第一行和第二行弄清楚如何指向您想要的数据。

现在让我们从左到右完成所涉及的步骤。

操作的第一部分采用pchar指向的字节,对字节和0x03执行逻辑AND,并将结果移位一位。

然后将该结果与下一个字节(*pchar+1)进行逻辑或运算,后者又与0x80进行“与”运算,然后右移7位。本质上,这部分只是剥离字节中的第一位并将其移位7位。

结果基本上是这样的:

想象一下pchar指向字节,其中的位用字母表示:ABCDEFGH

第一部分与0x03成对,因此我们留下了000000GH。然后将其左移一位,因此我们留下00000GH0

右边部分也是如此。 pchar+1代表IJKLMNOP。使用第一个逻辑AND,我们留下I0000000。然后右移7次。所以我们有0000000I。这与使用OR的左手部分组合在一起,因此我们有00000GHI,然后将其转换为int,它保持你的大小。

基本上,有三个位保持大小,但它们不是字节对齐的。因此,有必要进行一些操纵。

答案 3 :(得分:1)

size = (unsigned int)((((*pchar) & 0x03) << 1) | (((*(pchar+1)) & 0x80) >> 7));
  • 有人可以帮助我理解这个吗?

我们有字节*pchar和字节*(pchar+1)。每个字节由8位组成。 让我们将*pchar的每一位用粗体编号: 76543210 ,并将*(pchar+1)的每一位用斜体标记: 76543210

1 .. ((*pchar) & 0x03) << 1表示“除了位0和1之外的所有位*pchar为零,然后将结果向左移位1位”:

76543210 - &gt; xxxxxx10 - &gt;的 xxxxx10x

2 .. (((*(pchar+1)) & 0x80) >> 7)表示“除了第7位以外的所有*(pchar+1)位,然后将结果向右移7位”:

76543210 - &gt; 7xxxxxxx - &gt; xxxxxxx7

3 .. ((((*pchar) & 0x03) << 1) | (((*(pchar+1)) & 0x80) >> 7))表示“将左右操作数的所有非零位组合成一个字节”:

xxxxx10x | xxxxxxx7 - &gt;的 xxxxx10 7

因此,在结果中,我们有*pchar的两个低位和*(pchar+1)的一个高位。