6

各ビットが正確でなければならないソフトウェアを書いているので(CPU用です)、__packedは非常に重要です。

typedef union{
uint32_t raw;
struct{
    unsigned int present:1;
    unsigned int rw:1;
    unsigned int user:1;
    unsigned int dirty:1;
    unsigned int free:7;
    unsigned int frame:20;
} __packed;
}__packed page_union_t;

それが私の構造と結合です。ただし、機能しません。

page_union_t p; //.....
//This:
p.frame=trg_page;
p.user=user;
p.rw=rw;
p.present=present;
//and this:
p.raw=trg_page<<12 | user<<2 | rw<<1 | present;

同じ uint32 を作成する必要があります。しかし、それらは同じものを作成しません。

私の組合に問題がある、見えない何かがありますか?

4

5 に答える 5

10

構造体には31ビットしかありません

于 2009-06-11T02:44:05.043 に答える
6

AFAIK、構造体のビットが格納される順序は、C99標準(およびC89標準も)では定義されていません。ほとんどの場合、ビットは予想とは逆の順序になっています。

あなたはあなたが得た結果とあなたが期待した結果を示すべきでした-それは私たちの診断に役立ちます。使用するコンパイラと実行するプラットフォームも重要になる可能性があります。


MacOS X 10.4.11(PowerPC G4)では、次のコードは次のとおりです。

#include <inttypes.h>
#include <stdio.h>

typedef union
{
        uint32_t raw;
        struct
        {
                unsigned int present:1;
                unsigned int rw:1;
                unsigned int user:1;
                unsigned int dirty:1;
                unsigned int free:7;
                unsigned int frame:20;
        };
} page_union_t;

int main(void)
{
        page_union_t p = { .raw = 0 }; //.....
        unsigned trg_page = 0xA5A5A;
        unsigned user = 1;
        unsigned rw = 1;
        unsigned present = 1;

        p.frame = trg_page;
        p.user = user;
        p.rw = rw;
        p.present = present;

        printf("p.raw = 0x%08X\n", p.raw);

        p.raw = trg_page<<12 | user<<2 | rw<<1 | present;
        printf("p.raw = 0x%08X\n", p.raw);

        p.raw <<= 1;
        printf("p.raw = 0x%08X\n", p.raw);
        return(0);
}

示されている結果を生成します。

p.raw = 0xE014B4B4
p.raw = 0xA5A5A007
p.raw = 0x4B4B400E

フィールドの順序を逆にすると、結果はより説明しやすくなります。

#include <inttypes.h>
#include <stdio.h>

typedef union
{
        uint32_t raw;
        struct
        {
                unsigned int frame:20;
                unsigned int free:7;
                unsigned int dirty:1;
                unsigned int user:1;
                unsigned int rw:1;
                unsigned int present:1;
        };
} page_union_t;

int main(void)
{
        page_union_t p = { .raw = 0 }; //.....
        unsigned trg_page = 0xA5A5A;
        unsigned user = 1;
        unsigned rw = 1;
        unsigned present = 1;

        p.frame = trg_page;
        p.user = user;
        p.rw = rw;
        p.present = present;

        printf("p.raw = 0x%08X\n", p.raw);

        p.raw = trg_page<<12 | user<<2 | rw<<1 | present;
        printf("p.raw = 0x%08X\n", p.raw);

        p.raw <<= 1;
        printf("p.raw = 0x%08X\n", p.raw);
        return(0);
}

これにより、次の結果が得られます。

p.raw = 0xA5A5A00E
p.raw = 0xA5A5A007
p.raw = 0x4B4B400E

ビットフィールド構造には31ビットしか定義されていないため、最下位ビットが使用されないため、最初の結果の最後の16進数はEになります。

于 2009-06-11T02:46:27.050 に答える
2

ビットの正確な位置が重要な場合、最も安全な方法は、構造体をunsignedchar配列に明示的にパックおよびアンパックすることです。それ以外は実装に依存しすぎます。

于 2009-06-11T03:20:30.977 に答える
0

構造のビットを事前にクリアしているとは言いませんが、最初のケースでガベージビットが残ってしまうことはありませんか?

// maybe try this
page_union_t p = {0};
于 2009-06-11T02:45:03.093 に答える