Bit field

Bit field

From Wikipedia, the free encyclopedia

bit field is a structure used in computer programming to store multiple, logical, neighboring bits, where each of the sets of bits, and single bits can be addressed. A bit field is most commonly used to represent integral types of known, fixed bit-width.

For example, the first bit in a bit field can be used to determine the state of a particular attribute associated with the bit field.

Within microprocessors and other logic devices, flags (collection of bit fields) are commonly used to control or indicate the intermediate or final state or outcome of different operations. Microprocessors typically have, for example, a status register that is composed of such flags, and the flags are used to indicate various post-operation conditions, such as when there has been an arithmetic overflow. The flags can be utilized in subsequent operations, such as in processing conditional jump instructions. For example, a je (Jump if Equal) instruction in the x86 assembly language will result in a jump if the Z (zero) flag was set by some previous operation.

A bit field is distinguished[citation needed][according to whom?] from a bit array in that the latter is used to store a large set of bits indexed by integers and is often wider than any integral type supported by the language. Bit fields, on the other hand, typically fit within a machine word, and the denotation of bits is independent of their numerical index.

Implementation[edit]

Bit field can be used to reduce memory consumption when it is known that only some bits would be used for a variable. Bit fields allow efficient packaging of data in the memory.

As we know, integer takes two bytes(16-bits) in memory. Some times we need to store value that takes less than 2-bytes. In such cases, there is wastages of memory. For example, if we use a variable temp to store value either 0 or 1. In this case only one bit of memory will be used rather than 16-bits. By using bit field, we can save lot of memory.

In C and C++, native albeit implementation-defined bit fields can be created using unsigned int, signed int, or (in C99:) _Bool. In this case, "A bit field is set up with a structure declaration that labels each field and determines its width."[1] Adjacently declared bit fields of the same type can then be packed by the compiler into a reduced number of words, versus storing each 'field' totally separately as would be done with non-bitfield declaration syntax.

For languages lacking native bitfields, or where the programmer wants strict control and guarantees of the resulting bit representation, one can 'manually' manipulate bits within a larger word type. In this case, the programmer can set, test, and change the bits in the field using combinations of masking and bitwise operations. ORing a value will turn the bits on if they are not already on (leaving them unchanged if they are), e.g. someVariable |= BIT_MASK. To turn a bit off, you can AND its inverse, e.g. someVariable &= ~BIT_MASK;. You can toggle a bit (turn it on if it is off and off if it is on) with the XOR operator, e.g. someVariable ^= BIT_MASK;. To test a bit, you can use an AND expression, e.g. (someVariable & BIT_MASK;) ? true : false;

Retrieving the value of one particular bit can be simply done by left shifting (<<) the number 1, n amount of times (or, x << n - log2(x) amount of times, where x is a power of 2), where n is the index of the bit you want, e.g. if you want the value of the 4th bit in a binary number, you can do: 1 << 3; which will yield 8, or 2 << 2; etc. The benefits of this become apparent when iterating through a series of bits one at a time in a for loop, or when needing the powers of large numbers to check high bits.

Examples[edit]

Declaring a bit field in C:

#include <stdio.h>

// opaque and show
#define YES 1
#define NO  0

// line styles
#define SOLID  1
#define DOTTED 2
#define DASHED 3

// primary colors
#define BLUE  4  /* 100 */
#define GREEN 2  /* 010 */
#define RED   1  /* 001 */

// mixed colors
#define BLACK   0                    /* 000 */
#define YELLOW  (RED | GREEN)        /* 011 */
#define MAGENTA (RED | BLUE)         /* 101 */
#define CYAN    (GREEN | BLUE)       /* 110 */
#define WHITE   (RED | GREEN | BLUE) /* 111 */

const char * colors[8] = {"Black", "Red", "Green", "Yellow", "Blue", "Magenta", "Cyan", "White"};

// bit field box properties
struct box_props
{
     unsigned int opaque       : 1;
     unsigned int fill_color   : 3;
     unsigned int              : 4; // fill to 8 bits
     unsigned int show_border  : 1;
     unsigned int border_color : 3;
     unsigned int border_style : 2;
     unsigned int              : 0; // fill to nearest byte (16 bits)
     unsigned char width       : 4, // Split a byte into 2 fields of 4 bits
                   height      : 4;
};

[2]

Example of emulating bit fields with a primitive and bit operators in C:

/* Each prepocessor directive defines a single bit */
#define KEY_UP       (1 << 0)  /* 000001 */
#define KEY_RIGHT    (1 << 1)  /* 000010 */
#define KEY_DOWN     (1 << 2)  /* 000100 */
#define KEY_LEFT     (1 << 3)  /* 001000 */
#define KEY_BUTTON1  (1 << 4)  /* 010000 */
#define KEY_BUTTON2  (1 << 5)  /* 100000 */

int gameControllerStatus = 0;

/* Sets the gameControllerStatus using OR */
void keyPressed(int key) {
     gameControllerStatus |= key;
}

/* Turns the key in gameControllerStatus off using AND and ~ (binary NOT)*/
void keyReleased(int key) {
    gameControllerStatus &= ~key;
}

/* Tests whether a bit is set using AND */
int isPressed(int key) {
    return gameControllerStatus & key;
}

Processor status register[edit]

Taking the example of a 6502 processor's status register, the following information was held within 8 bits:

  • Bit 7. Negative flag
  • Bit 6. Overflow flag
  • Bit 5. Unused
  • Bit 4. Break flag
  • Bit 3. Decimal flag
  • Bit 2. Interrupt-disable flag
  • Bit 1. Carry flag
  • Bit 0. Zero flag

Unix process exit code[edit]

A more general example would be the use of a Unix exit status as a flag word. In this case, the exit code is used by the programmer to pass status information to another process. An imaginary program which returns the status of 8 burglar alarm switches connected to the printer port could set each of the bits in the exit code in turn, depending on whether the switches are closed or open.

Extracting bits from flag words[edit]

A subset of flags in a flag field may be extracted by ANDing with a mask.

Suppose that status byte 103 (decimal) is returned, and that we want to check flag bit 5.

The flag we want to read is number 5 (counting from zero) - so the mask byte will be {\displaystyle 2^{5}=32}2^{5}=32. ANDing 32 with 103 gives 32, which means the flag bit is set. If the flag bit was not set, the result would have been 0.

In many languages, the shift operator (<<) can be used to perform the power-of-two. In general, a mask with the Nth bit set can be computed as

(1 << n)

Thus to check the Nth bit from a variable v, we can perform the operation

bool nth_is_set = (v & (1 << n)) != 0

Changing bits in flag words[edit]

Writing, reading or toggling bits in flags can be done only using the OR, AND and NOT operations - operations which can be performed quickly in the processor.

To set a bit, OR the status byte with a mask byte. Any bits set in the mask byte or the status byte will be set in the result.

 int set_bit(int val, int bit_position)
 {
   return val | (1 << bit_position);
 }

To clear a bit, perform a NOT operation on the mask byte, then AND it with the status byte. The result will have the appropriate flag cleared (set to 0).

 int clear_bit(int val, int bit_position)
 {
   return val & ~(1 << bit_position);
 }

To toggle a bit, XOR the status byte and the mask byte. This will set a bit if it is cleared or clear a bit if it is set.

 int toggle_bit(int val, int bit_position)
 {
   return val ^ (1 << bit_position);
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值