문제

나는 각 비트가 정확 해야하는 소프트웨어를 작성하고 있습니다 (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를 생성해야합니다. 그러나 그들은 같은 것을 만들지 않습니다.

내 노조에 잘못된 것을 볼 수없는 것이 있습니까?

도움이 되었습니까?

해결책

구조물에는 31 비트 만 있습니다

다른 팁

구조물의 비트가 저장되는 순서는 C99 표준 (및 C89 표준)에 의해 정의되지 않은 Afaik. 아마도 비트는 예상했던 것과 반대 순서입니다.

당신은 당신이 얻은 결과와 당신이 기대 한 결과를 보여 주었을 것입니다 - 그것은 진단에 도움이 될 것입니다. 사용하는 컴파일러와 실행하는 플랫폼도 중요 할 수 있습니다.


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 비트가 정의되어 있기 때문에 첫 번째 결과는 최소한의 유의 한 비트가 사용되지 않기 때문에 E를 마지막 16 진수로 사용합니다.

비트의 정확한 위치가 중요하다면, 가장 안전한 베팅은 명백한 포장 및 구조를 서명되지 않은 Char 어레이로 풀고 풀리는 것입니다. 다른 모든 것은 너무 구현에 따라 다릅니다.

이것을 찾을 수있는 사람과 관련하여 포장 된 속성을 시도하십시오.

struct __attribute__((packed)){

}

당신은 당신이 사전에 구조물의 비트를 제거하고 있다고 언급하지 않습니다. 첫 번째 경우에는 쓰레기 비트가 남아 있지 않습니까?

// maybe try this
page_union_t p = {0};
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top