bit field hakkında

Peak2Peak

Aktif Üye
Katılım
27 Haziran 2020
Mesajlar
272
C:
#include <stdio.h>
#include <stdint.h>

struct date {
   int d : 4;
   int m : 4;
};

int main()
{
   uint8_t a;

   printf("Size of date is %lu bytes\n",
          sizeof(struct date));

   struct date dt = {1,3};
   printf("Date is %d/%d", dt.d, dt.m);

   a=dt.d|dt.m;
   printf("\n%d",a);

}

C 'de hiç bilmediğim yerlere bakıyordum.Bit field dedikler şeyi ile karşılaştım.Donanımda kullanılıyormuş..Bazı yerlerde kafa karıştı.
struct içinde 4 bitlik iki değişkenim var.size off ile baktığım 4 bayt tuttuğunu gördüm.4 bayt çok fazla galiba sistemden sisteme değişiyormuş.
bu bitlerin sıralamasını anlayamadım.4 bayt içinde nasıl sıralanıyor.
2 adet 4 biti or yapıp toplamayı tek bayt içinde yazmayı denedim.sonuçlar istediğim gibi çıkmadı.Bitlerin yeri aynı olunca sonuç değişmiyor.kaydırmam gerekiyor sanırım ama nasıl sıraladığını bulamadım yardımcı olabilir misin?
 
Bit field'lerin en yaygın kullanım şekli, gene bir C yapısı olan union ile birlikte kullanmaktır. Böyle bir yapı, mesela bir işlemcinin donanım registerlerine erişimi oldukça kolaylaştırır, programın da anlaşılabilirliğini arttırır. Aşağıdaki basit örneği incele. Burada bir union tanımlıyoruz. İçinde de date_int ve date_bit değişkenleri var. Buradaki union tanımı, date_int ve date_bit değişkenlerinin örtüşmesini sağlıyor. Birinde yapılan değişiklik diğerini de güncelliyor.

C:
#include <stdio.h>

union theunion
{
   unsigned int date_int;

   struct
   {
      unsigned int a : 3;
      unsigned int b : 3;
      unsigned int c : 2;

   } date_bit;
};

int main()
{
   union theunion s;

   printf("sizeof(s) = %u\n", sizeof(s));

   s.date_bit.a = 3;
   s.date_bit.b = 2;
   s.date_bit.c = 1;

   printf("s.date_int = 0x%x\n", s.date_int);

   s.date_int = 0xb3;

   printf("s.date_bit.a = %x\n", s.date_bit.a);
   printf("s.date_bit.b = %x\n", s.date_bit.b);
   printf("s.date_bit.c = %x\n", s.date_bit.c);
}
 
Aşağıda da şuanda üzerinde çalıştığım Renesas'ın RA6M2 işlemcisinin kütüphanesinden bir örnek var. Burada bir 16 bitlik bir kontrol registerinin yapısı tanımlanıyor.

C:
    union CS0CR
    {
        __IOM uint16_t CR;             /*!< (@ 0x00000002) Control Register                                           */

        struct
        {
            __IOM uint16_t EXENB : 1;  /*!< [0..0] Operation Enable                                                   */
            uint16_t             : 3;
            __IOM uint16_t BSIZE : 2;  /*!< [5..4] External Bus Width Select                                          */
            uint16_t             : 2;
            __IOM uint16_t EMODE : 1;  /*!< [8..8] Endian Mode                                                        */
            uint16_t             : 3;
            __IOM uint16_t MPXEN : 1;  /*!< [12..12] Address/Data Multiplexed I/O Interface Select                    */
            uint16_t             : 3;
        } CR_b;
    };

Bu registerin teknik dokümandaki açıklaması da şurada:
1639574586330.png


Şimdi, bir C programında ben bu kontrol registerine istediğim gibi erişebileceğim artık:

C:
int main()
{
   union CS0CR reg;

   unsigned int temp;

   /* status register read individual fields */
   temp = reg.CR_b.EXENB;
   temp = reg.CR_b.BSIZE;

   /* status registere write individual fields */
   reg.CR_b.EXENB = 1;
   reg.CR_b.BSIZE = 2;
   reg.CR_b.EMODE = 1;
   reg.CR_b.MPXEN = 1;

   /* read all fields */
   temp = REG.CR;

   /* write all fields */
   reg.CR = 0x1423;
}
 
union değişkenleri aynı hafızayı kulladığı değişimler birbirini etkiliyor sanırım
bu MSB LSB neye göre belirleniyor.
a değişkeni LSB olmuş
 
Son düzenleme:
Bit field'lerin en yaygın kullanım şekli, gene bir C yapısı olan union ile birlikte kullanmaktır. Böyle bir yapı, mesela bir işlemcinin donanım registerlerine erişimi oldukça kolaylaştırır, programın da anlaşılabilirliğini arttırır. Aşağıdaki basit örneği incele. Burada bir union tanımlıyoruz. İçinde de date_int ve date_bit değişkenleri var. Buradaki union tanımı, date_int ve date_bit değişkenlerinin örtüşmesini sağlıyor. Birinde yapılan değişiklik diğerini de güncelliyor.

C:
#include <stdio.h>

union theunion
{
   unsigned int date_int;

   struct
   {
      unsigned int a : 3;
      unsigned int b : 3;
      unsigned int c : 2;

   } date_bit;
};

int main()
{
   union theunion s;

   printf("sizeof(s) = %u\n", sizeof(s));

   s.date_bit.a = 3;
   s.date_bit.b = 2;
   s.date_bit.c = 1;

   printf("s.date_int = 0x%x\n", s.date_int);

   s.date_int = 0xb3;

   printf("s.date_bit.a = %x\n", s.date_bit.a);
   printf("s.date_bit.b = %x\n", s.date_bit.b);
   printf("s.date_bit.c = %x\n", s.date_bit.c);
}

Forumdaki eski konulara bakarken gözüme çarptı bu yanıtınız. Açıkçası kodun çıktısının neden böyle olduğunu anlayamadım. Öncelikle ben union içerisindeki en büyük hafızayı kaplayan üye kadar hafıza kaplıyor olarak biliyorum. Bu kodda structure 12 byte, int 4 byte yer kaplıyor. Union'ın hafızasının 12 byte olması gerekmez miydi ?

Bir de müsait olduğunuz bir vakitte bu kodun nasıl bu şekilde bir çıktı verdiğini anlatabilir misiniz acaba?
 
Oradaki struct "bit field", yani her değişken belli bitleri ifade ediyor. O yüzden struct'ın kapladığı byte sayısı sizeof(unsigned int) ifadesine eşittir.

Mesela programı benim linux makina için derlersem şu çıktıyı alıyorum:

Bash:
[ta@bonsai ~]$ gcc a.c
[ta@bonsai ~]$ ./a.out
sizeof(s) = 4
s.date_int = 0x53
s.date_bit.a = 3
s.date_bit.b = 6
s.date_bit.c = 2
[ta@bonsai ~]$
 

Forum istatistikleri

Konular
5,659
Mesajlar
97,353
Üyeler
2,438
Son üye
İbrahimSönmez

Son kaynaklar

Son profil mesajları

cemalettin keçeci wrote on HaydarBaris's profile.
barış kardeşim bende bu sene akıllı denizaltı projesine girdim ve sensörleri arastırıyorum tam olarak hangi sensör ve markaları kullandınız yardımcı olabilir misin?
m.white wrote on Altair's profile.
İyi akşamlar.Arabanız ne marka ve sorunu nedir.Ben araba tamircisi değilim ama tamirden anlarım.
* En mühim ve feyizli vazifelerimiz millî eğitim işleridir. Millî eğitim işlerinde mutlaka muzaffer olmak lâzımdır. Bir milletin hakikî kurtuluşu ancak bu suretle olur. (1922)
Kesici/Spindle hızı hesaplamak için SpreadSheet UDF'leri kullanın, hesap makinesi çok eski kalan bir yöntem :)
Dr. Bülent Başaran,
Elektrik ve Elektronik Mühendisi
Yonga Tasarım Özdevinimcisi
Üç güzel "çocuk" babası
Ortahisar/Ürgüp/Konya/Ankara/Pittsburgh/San Francisco/Atlanta/Alaçatı/Taşucu...

Back
Top