For example, in order to initialize the registers of the serial interface RS232 (V24) with correct values or to query the status of the interface and to send or receive a byte, it is necessary to understand the functions for bit manipulation and to be able to use them safely.
Gambas provides several functions for bit manipulation:
These instructions apply to all functions in the following table for the arguments Number and Bit:
The valid range of bits Bk depends on the data type of the argument Number. The following applies:
Data-Typ Bit-Domain -------------------------- Byte B0...B7 Short B0...B15 Integer B0...B31 Long B0...B63
Function | Description |
---|---|
BClr (Number, Bit) | Returns number with deleted bit' Bit'. |
BSet (Number, Bit) | Returns number with bit' Bit' set. |
BTst (Number, Bit) | Returns True if bit' Bit' is set, otherwise False. |
BChg (Number, Bit) | Returns Number whose bit' Bit' was inverted. |
Lsl (Number, Bit) | Each bit in the bit sequence of Number is shifted to the left by' Bit' bits. For the left-hand bits that are omitted, zero bits are attached to the right-hand side. The sign is ignored. (Lsl = logical shift left) |
Lsr (Number, Bit) | Each bit in the bit sequence of Number is shifted to the right by' Bit' bits. Zero bits are inserted on the left for the bits that are omitted on the right. (Lsr = logical shift right) |
Shl (Number, Bit) | Each bit in the bit sequence of Number is shifted to the left by' Bit' bits. For the left-hand bits that are omitted, zero bits are attached to the right-hand side. |
Asl (Count, Bit) | Synonym for Shl (count, bit). The sign is not ignored. |
Shr (Number, Bit) | Each bit in the bit sequence of Number is shifted to the right by' Bit' bits. The sign bit is inserted on the left for the bits that are omitted on the right. |
Asr (Number, Bit) | Synonym for Shr (Number, Bit) |
Rol (Number, Bit) | During the operation Rol, the bits rotate by the number of' bits' as if MSB (most significant bit - highest value bit position) and LSB (less significant bit - lowest value bit position) were connected to each other. The bit that is shifted out of the bit sequence to the left has the same value as the bit that is shifted in from the right. (Rol = Rotate left) |
Ror (Number, Bit) | During operation Ror(), the bits rotate by the number of 'bits' as if MSB and LSB were connected to each other. The bit that is shifted out of the bit sequence to the right has the same value as the bit that is shifted in from the left. |
Table 9.9.1.1: Overview of the functions for bit manipulation
An example is given for each of the above-mentioned functions for bit manipulation:
Print 23; " -> "; Bin(CByte(23), 8); " BCLR(CByte(23),2) "; Bin(BClr(CByte(23), 2), 8); " ->> "; BClr(CByte(23), 2) Print 23; " -> "; Bin(CByte(23), 8); " BSET(CByte(23),3) "; Bin(BSet(CByte(23), 3), 8); " ->> "; BSet(CByte(23), 3) Print 23; " -> "; Bin(CByte(23), 8); " BCHG(CByte(23),1) "; Bin(BChg(CByte(23), 1), 8); " ->> "; BChg(CByte(23), 1) Print 23; " -> "; Bin(CByte(23), 8); " ->> "; IIf(BTst(CByte(23), 2), "The Bit B2 is set!", "The Bit B2 is 0.") Print Print 23; " -> "; Bin(CByte(23), 8); " LSL(CByte(23),3) "; Bin(Lsl(CByte(23), 3), 8); " ->> "; Lsl(CByte(23), 3) Print 23; " -> "; Bin(CByte(23), 8); " LSR(CByte(23),3) "; Bin(Lsr(CByte(23), 3), 8); " ->> "; Lsr(CByte(23), 3) Print Print +23; " -> "; Bin(CShort(23), 16); " SHL(CShort(23),3) "; Bin(Shl(CShort(23), 3), 16); " ->> "; Shl(CShort(23), 3) Print -23; " -> "; Bin(CShort(-23), 16); " SHR(CShort(-23),3) "; Bin(Shr(CShort(-23), 3), 16); " ->> "; Shr(CShort(-23), 3) Print Print 23; " -> "; Bin(CShort(23), 16); " ROL(CShort(23),3) "; Bin(Rol(CShort(23), 3), 16); " ->> "; Rol(CShort(23), 3) Print 23; " -> "; Bin(CShort(23), 16); " ROR(CShort(23),3) "; Bin(Ror(CShort(23), 3), 16); " ->> "; Ror(CShort(23), 3) Print Print 23; " -> "; Bin(CByte(23), 8); " NOT 23 "; Bin(Not CByte(22), 8); " ->> "; Not 23
Output in the console of the IDE:
23 -> 00010111 BCLR(CByte(23),2) 00010011 ->> 19 23 -> 00010111 BSET(CByte(23),3) 00011111 ->> 31 23 -> 00010111 BCHG(CByte(23),1) 00010101 ->> 21 23 -> 00010111 ->> The Bit B2 is set! 23 -> 00010111 LSL(CByte(23),3) 10111000 ->> 184 23 -> 00010111 LSR(CByte(23),3) 00000010 ->> 2 23 -> 0000000000010111 SHL(CShort(23),3) 0000000010111000 ->> 184 -23 -> 1111111111101001 SHR(CShort(-23),3) 1111111111111101 ->> -3 23 -> 0000000000010111 ROL(CShort(23),3) 0000000010111000 ->> 184 23 -> 0000000000010111 ROR(CShort(23),3) 1110000000000010 ->> -8190 23 -> 00010111 NOT 23 11101001 ->> -24
The functions BClr (number, bit), BSet (number, bit), BChg (number, bit) and BTst (number, bit) in Table 9.9.1.1 above apply to the following functions:
Exactly one bit is changed or its (bit) value is queried.
In some programming languages, bit operators exist in addition to the logical operators such as AND or OR or NOT. Since Gambas does not know any special (logical) bit operators, you can apply the logical operators to operands that exist as numbers of the data type Byte, Short, Integer or Long. This allows you to set or delete or invert several bits in a bit sequence simultaneously (simultaneously).
operand : (10011011)bin = (155)dez mask : (00100100)bin = (36)dez result : (10111111)bin = (191)dez
To generate the required bit masks it is advantageous to have the operators as binary numbers. Since each bit of the operand is linked to each bit of the bit mask with the logical operators, the knowledge of the following tables is helpful:
A B A AND B ----------------------- 0 0 0 0 1 0 1 0 0 1 1 1 A B A OR B ---------------------- 0 0 0 0 1 1 1 0 1 1 1 1 A B A XOR B ----------------------- 0 0 0 0 1 1 1 0 1 1 1 0 A NOT A ------------- 0 1 1 0
Bit B3 and bit B4 in the operand (10011011)bin = 155dec are to be deleted while all other bits do not change their value.
By using the AND operator with operand AND mask, only the bits B3 and B4 are deleted if you use a bit mask mask with the value 0 at the bit positions to be deleted and otherwise 1.
operand : (10011011)bin = (155)dez mask : (11100111)bin = (231)dez result : (10000011)bin = (131)dez
The four bits B0 to B3 in the operand (10011011)bin = 155dec are to be inverted and all other bits retain their value. The appropriate bit mask has the value 1 at the bit positions to be inverted and otherwise 0. operand XOR mask ensures that only the first 4 low-order bits are inverted:
operand : (10011011)bin = (155)dez mask : (00001111)bin = (15)dez result : (10010100)bin = (148)dez
All bits in the operand (10011011)bin = 155dec are to be inverted. With operand XOR mask, all bits are inverted if the bit mask has the value 1 at all bit positions:
operand : (10011011)bin = (155)dez mask : (11111111)bin = (255)dez result : (01100100)bin = (100)dez
A fast alternative is the NOT operator, as a logical negation of each bit is performed with bitwise NOT. Each 1 is replaced by 0 and each 0 by 1:
NOT (155) = 100 NOT (10011011) = 01100100
Summary:
For testing tasks 1 to 4, the BitManipulation function (bOperand As Byte, sMode As String, Optional sMask As Byte[]) was used, in which you can use the operators AND, OR, XOR and NOT and an example procedure:
Public Function BitManipulation(bOperand As Byte, sOperation As String, Optional sMask As Byte[]) As Byte Dim bBitMask, bElement As Byte Dim k As Integer If sMask Then sMask.Reverse() For k = 0 To 7 bBitMask = bBitMask + sMask[k] * 2 ^ k Next Endif Select Case Upper(sOperation) Case "NOT" Return Not bOperand Case "AND" Return bOperand And bBitMask Case "OR" Return bOperand Or bBitMask Case "XOR" Return bOperand Xor bBitMask End Select End ' BitManipulation(..) Public Sub btnClearBits_Click() Print NumberToDezimal("10011011", 2) ' For control: number, base Print NumberToDezimal("11100111", 2) Print Bin(BitManipulation(155, "AND", [1, 1, 1, 0, 0, 1, 1, 1]), 8) Print NumberToDezimal("10000011", 2) End ' btnClearBits_Click()