bit pattern으로 된 union 선언시 bit order 문제..

vyoz의 이미지

typedef union __bt_u{
 
    struct _byte_data{
        unsigned char byte;
    }byte_data;   
 
    struct __bit_test{
        unsigned char b1:1;
        unsigned char b2:1;
        unsigned char b3:1;
        unsigned char b4:1;
        unsigned char b5:1;
        unsigned char b6:1;
        unsigned char b7:1;
        unsigned char b8:1;
    }bit_test;
}bt_u;

이렇게 union을 선언해놓고

bt_u mybt = 0xE0;

이렇게 값을 넣어줬습니다.

제가 기대한것은
b1=1, b2=1, b3=1, b4=0 ... b8=0(순서대로: 1110 0000)으로
셋팅되기를 기대했습니다.하지만 실제로 해보니
b1=0, b2=0 ... b6=1, b7=1, b8=1(순서대로: 0000 0111)으로
셋팅이됩니다. cx86202이란 arm 계열 cpu+linux 환경과
intel cpu+windows(VC++) 환경에서 테스트해봤는데 둘 다 같은 결과를 보여줍니다.

왜 그런걸까요?

kewlbear의 이미지

비트가 할당되는 방법은 구현체에 의존적입니다.
원하시는 대로 매핑이 되어야 한다면 비트 연산자를 쓰십시요.

irondog의 이미지

8비트 값이기에 엔디안이 어떻든간에 같은 결과를 돌려 주는 것이 논리적으로 맞아 보입니다만...
그리고 16비트나 32비트에서도 아마 같은 결과가 나오지 않을까 싶네요.
structure도 위에 선언된 변수보다 아래 선언된 변수가 메모리 위치/주소 상 뒤에 위치할테니까요.

vyoz의 이미지

typedef union __bt_u{
    unsigned long fourbyte;
 
    struct _byte_data{
        unsigned char byte[4];
    }byte_data; 
 
    struct __bit_test{
        unsigned char b1:1;
        unsigned char b2:1;
        unsigned char b3:1;
        unsigned char b4:1;
        ...
        unsigned char b32:1;
    }bit_test;
}bt_u;

이런식으로 bt_u mydata = fourbyte = 0x0000E000; 넣어주면 32bit 단위로 bit order가 바뀝니다.

제가 생각할땐

0000(0) 0000(0) 0000(0) 0000(0) 1110(E) 0000(0) 0000(0) 0000(0)

이런 순서로 들어가있어야 한다고 생각했는데 실제로 b1 ~ b32까지 출력을 해보면

0000(0) 0000(0) 0000(0) 0111(7) 0000(0) 0000(0) 0000(0) 0000(0)

로 순서가 바뀝니다.

bt_u mydata;
mydata.bytedata.byte[0] = 0x00;
mydata.bytedata.byte[1] = 0x00;
mydata.bytedata.byte[2] = 0xE0;
mydata.bytedata.byte[3] = 0x00;

로 넣을경우 8bit씩 bit order가 역순이됩니다.

왜 이럴까요? 으...

hie의 이미지

말 그대로 Little과 Big의 의미를 잘 생각해 보면 그 차이를 알 수 있습니다.
Little은 LSB부터.. Big은 MSB부터.. 따라서 Bit-struct를 선언하실때
Little인 경우는 LSB부터 선언해 주셔야 합니다.

[irondog 씀]

8비트 값이기에 엔디안이 어떻든간에 같은 결과를 돌려 주는 것이 논리적으로 맞아 보입니다만...

그렇지 않습니다. Byte-ordering이 1바이트 내에서는 Little과 Big이 동일하다는 것이지
Bit-ordering이 동일하다는 것이 아닙니다.

[vyoz 씀]

typedef union __bt_u{
    unsigned long fourbyte;
 
    struct _byte_data{
        unsigned char byte[4];
    }byte_data; 
 
    struct __bit_test{
        unsigned char b1:1;
        unsigned char b2:1;
        unsigned char b3:1;
        unsigned char b4:1;
        ...
        unsigned char b32:1;
    }bit_test;
}bt_u;

만약 상기코드를 다음과 같이 하면 어떻게 될까요??

typedef union __bt_u{
    unsigned long fourbyte;
 
    struct _byte_data{
        unsigned char byte[4];
    }byte_data; 
 
    struct __bit_test{
        unsigned long b1:1;
        unsigned long b2:1;
        unsigned long b3:1;
        unsigned long b4:1;
        ...
        unsigned long b32:1;
    }bit_test;
}bt_u;

직접 해 보시면 Byte-ordering 및 Bit-ordering에 대한 차이 및 이해를
확실히 할 수 있을 것입니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.