# Lecture 6 Data Representation and Bit Manipulation in C

Shared by:
Categories
-
Stats
views:
36
posted:
5/25/2010
language:
English
pages:
63
Document Sample

```							TDDI11: Embedded Software

Lecture 6:
Data Representation
and Bit Manipulation in C
Lecture outline

• Representation of data
– Integer, reals, characters, strings
• Data types in C
– Integer data types, mixing data types, typedefs
• Bit manipulation in C
– Testing bits
– Setting, clearing and inverting bits
– Extracting and inserting bits

Lecture 6/2
Kinds of data

• Numbers                      • Text
– Integers                     – ASCII Characters
• Unsigned                  – Strings
• Signed
• Other
– Reals
–   Graphics
• Fixed-Point
• Floating-Point            –   Images
–   Video
–   Audio

Lecture 6/3
Numbers are different!

• Computers use binary (not decimal) numbers (0's
and 1's).
– Requires more digits to represent the same magnitude.

• Computers store and process numbers using a fixed
number of digits (“fixed-precision”).

• Computers represent signed numbers using 2's
complement instead of sign-plus-magnitude (not our
familiar “sign-plus-magnitude”).

Lecture 6/4
Representation rollover

•   Consequence of fixed precision.
•   Computers use fixed precision!
•   Digits are lost on the left-hand end.
•   Remaining digits are still correct.
•   Rollover while counting . . .
Up: “999999” ! “000000” (Rn-1 ! 0)
Down: “000000” ! “999999” (0 ! Rn-1 )

Lecture 6/5
Rollover in unsigned binary

• Consider an 8-bit byte used to represent an
unsigned integer:
– Range: 00000000 ! 11111111 (0 ! 25510)
– Incrementing a value of 255 should yield 256, but this
exceeds the range.
– Decrementing a value of 0 should yield –1, but this
exceeds the range.
– Exceeding the range is known as overflow.

Lecture 6/6
Rollover is not synonymous with overflow!

• Rollover describes a pattern sequence
behavior.
• Overflow describes an arithmetic behavior.
• Whether or not rollover causes overflow
depends on how the patterns are interpreted
as numeric values!
– E.g., In signed two’s complement representation,
11111111 !00000000 corresponds to counting
from minus one to zero.

Lecture 6/7

• The number of digit symbols is determined by the radix (e.g., 16)
• The value of the digit symbols range from 0 to 15 (0 to R-1).
• The symbols are 0-9 followed by A-F.
• Conversion between binary and hex is trivial!
• Use as a shorthand for binary (significantly fewer digits are required
for same magnitude).

Lecture 6/8
Memorize this!

Hex   Binary         Hex     Binary
0    0000            8      1000
1    0001            9      1001
2    0010            A      1010
3    0011               B   1011
4    0100               C   1100
5    0101               D   1101
6    0110               E   1110
7    0111               F   1111

Lecture 6/9
Binary/hex conversions

Hex digits are in one-to-one correspondence with
groups of four binary digits:
0011 1010 0101 0110 . 1110 0010 1111 1000
3       A      5       6     .     E       2      F         8

• Conversion is a simple table lookup!
• Zero-fill on left and right ends to complete the groups!
• Works because 16 = 24 (power relationship)

Lecture 6/10
Two interpretations

unsigned                signed
16710              101001112                 -8910

• Signed vs. unsigned is a matter of
interpretation; thus a single bit pattern can
represent two different values.
• Allowing both interpretations is useful:
Some data (e.g., count, age) can never be
negative, and having a greater range is
useful.
Lecture 6/11
Why not sign+magnitude?

+3   0011   • Complicates addition :
– To add, first check the signs. If they agree,
+2   0010        then add the magnitudes and use the same
+1   0001        sign; else subtract the smaller from the
larger and use the sign of the larger.
+0   0000
-0   1000      – How do you determine which is
smaller/larger?
-1   1001
-2   1010   • Complicates comparators:
-3   1011      – Two zeroes!

Lecture 6/12
Why 2’s complement?

1. Just as easy to determine sign
+3   0011      as in sign+magnitude.
+2   0010   2. Almost as easy to change the
+1   0001      sign of a number.
0   0000   3. Addition can proceed w/out
-1   1111      worrying about which operand is
-2   1110      larger.
-3   1101   4. A single zero!
-4   1100   5. One hardware adder works for
both signed and unsigned
operands.
Lecture 6/13
Changing the sign

Sign+Magnitude:           2’s Complement:
+4 = 0100                 +4 = 0100
Change 1 bit                     Invert

-4 = 1100                 +4 = 1011
+1      Increment

-4 = 1100

Lecture 6/14
Range of unsigned integers

Each of ‘n’ bits can have one of two values.
Total # of patterns of n bits = 2× 2× 2×… 2
‘n’ 2’s
= 2n
If n-bits are used to represent an unsigned
integer value:
Range: 0 to 2n-1 (2n different values)

Lecture 6/15
Range of signed integers

• Half of the 2n patterns will be used for positive
values, and half for negative.

• Half is 2n-1.

• Positive Range: 0 to 2n-1-1 (2n-1 patterns)
• Negative Range: -2n-1 to -1 (2n-1 patterns)

• 8-Bits (n = 8): -27 (-128) to +27-1 (+127)

Lecture 6/16
Unsigned overflow

1100    (12)       Value of lost bit is 2n (16).
+0111    ( 7)              16 + 3 = 19
Lost
(Result limited by word size)

0011     ( 3) wrong
Lecture 6/17
Signed overflow

-12010    !            100010002
-1710                +111011112
sum: -13710                1011101112
011101112 (keep 8 bits)
(+11910) wrong

Note: 119 – 28 = 119 – 256 = -137
Lecture 6/18
Floating-point reals
31   30      23   22                                        0

±    Exponent          Fractional Bits of Significand

Three components:
Base is implied

± significand × 2exponent
A biased
Sign                                                      integer value

An unsigned fractional value

Lecture 6/19
Fixed-point reals

Three components:
Implied binary point

0⋅ ⋅ ⋅ 00.00 ⋅ ⋅ ⋅0

Whole part                                    Fractional part

Lecture 6/20
Fixed vs. floating

• Floating-Point:
Pro: Large dynamic range determined by
exponent; resolution determined by significand.
Con: Implementation of arithmetic in hardware is
complex (slow).

• Fixed-Point:
Pro: Arithmetic is implemented using regular
integer operations of processor (fast).
Con: Limited range and resolution.

Lecture 6/21
Representation of characters

Representation           Interpretation

00100100                    \$
ASCII
Code

Lecture 6/22
Representation of strings

48 65 6C 6C 6F 00        C uses a
terminating
H   e   l   l   o        “NUL” byte of
Pascal uses a                               all zeros at
prefix count                                the end of
at the                                      the string.
beginning of
the string.
05 48 65 6C 6C 6F
H   e   l   l   o
Lecture 6/23
Example: Representation of Strings

Lecture 6/24
Basic names for integer types:
char and int

• unsigned, signed, short, and long are modifiers

• If one or more modifiers is used,
int is assumed and may be omitted.

• If neither signed or unsigned is used,
signed is assumed and may be omitted.

• int with no modifier is a data type
whose size varies among compilers.

Lecture 6/25
Integer data types

Data Type       Size       Range
unsigned char      8 bits     0 to 255
short int 16 bits    0 to 65,535
int       16 or 32   16 bits: same as unsigned short int;
bits       32 bits: same as unsigned long int.
long int 32 bits     0 to 4,294,967,295
signed char      8 bits     -128 to +127
short int 16 bits    -32,768 to +32,767
int       16 or 32   16 bits: same as signed short int;
bits       32 bits: same as signed long int.
long int 32 bits     -2,147,483,648 to +2,147,483,647

Lecture 6/26
Contents of ANSI File (limits.h)

#define SCHAR_MIN         -127
#define SCHAR_MAX          127

#define SHRT_MIN        -32767
#define SHRT_MAX         32767

#define INT_MIN     -2147483647
#define INT_MAX      2147483647

#define LONG_MIN    -2147483647
#define LONG_MAX     2147483647

Lecture 6/27
typedefs

unsigned long int count ;

versus

typedef unsigned long int DWORD32 ;
DWORD32 count ;

Lecture 6/28
typedefs and #defines

typedef unsigned char        BYTE8 ;
typedef unsigned short int   WORD16 ;
typedef unsigned long int    DWORD32 ;

typedef int                  BOOL ;
#define FALSE                0
#define TRUE                 1

Lecture 6/29
Packed operands

Bits 15 - 11     Bits 10 - 5         Bits 4 - 0
Hours          Minutes          Seconds ÷ 2
MS/DOS packed representation of time.

Bit 7      Bit 6    Bit 5    Bit 4     Bit 3     Bit 2  Bit 1   Bit 0
Carrier     Ring    Data Set Clear To ∆ Carrier Ring    ∆ Data ∆ Clear
Detect    Indicator Ready     Send     Detect Indicator Set Rdy To Send
UART modem status port

Bit 7      Bit 6        Bit 5      Bit 4      Bit 3      Bit 2    Bit 1     Bit 0
Enable     Select    Initialize Auto      Data
Reserved Reserved Reserved
IRQ       Printer    Printer LineFeed   Strobe
IBM-PC printer control port

Lecture 6/30
Boolean and binary operators

Operation   Boolean Operator Bitwise Operator
AND              &&                &
OR               ||                |
XOR          unsupported            ^
NOT              !                ~

•Boolean operators are primarily used to
form conditional expressions (as in an if
statement)
•Bitwise operators are used to manipulate
bits.
Lecture 6/31
Boolean values

• Most implementations of C don't provide a
Boolean data type.
• Boolean operators yield results of type int, with
true and false represented by 1 and 0.
• Any numeric data type may be used as a Boolean
operand.
• Zero is interpreted as false; any non-zero value is
interpreted as true.

Lecture 6/32
Boolean expressions

(5 || !3) && 6

= (true OR (NOT true)) AND true
= (true OR false) AND true
= (true) AND true
= true
=1

Lecture 6/33
Bitwise operators

•   Bitwise operators operate on individual bit
positions within the operands

•   The result in any one bit position is entirely
independent of all the other bit positions.

Lecture 6/34
Bitwise expressions

(5 | ~3) & 6

= (00..0101 OR ~00..0011) AND 00..0110
= (00..0101 OR 11..1100) AND 00..0110
= (11..1101) AND 00..0110
= 00..0100
=4

Lecture 6/35
Interpreting the bitwise-AND

m p m AND p        Interpretation
0 0       If bit m of the mask is 0,
0       0   bit p is cleared to 0 in
1 0       the result.
0 0          If bit m of the mask is 1,
1           p    bit p is passed through
1 1          to the result unchanged.

Lecture 6/36
Interpreting the bitwise-OR

m p m OR p          Interpretation
0 0          If bit m of the mask is 0,
0      p       bit p is passed through
1 1          to the result unchanged.
0 1        If bit m of the mask is 1,
1          1   bit p is set to 1 in
1 1        the result.

Lecture 6/37
Interpreting the bitwise-XOR

m p m XOR p        Interpretation
0 0       If bit m of the mask is 0,
0       p   bit p is passed through
1 1       to the result unchanged.
0 1       If bit m of the mask is 1,
1      ~p   bit p is passed through
1 0       to the result inverted.

Lecture 6/38
Testing bits

• A 1 in the bit position of interest is AND'ed with the
operand. The result is non-zero if and only if the bit
of interest was 1:

if ((bits & 64) != 0)    /* check to see if bit 6 is set */

b7b6b5b4b3b2b1b0   &   01000000          0b6000000

Lecture 6/39
Testing bits, cont.

• Since any non-zero value is interpreted as true,
the redundant comparison to zero may be
omitted, as in:

if (bits & 64) /* check to see if bit 6 is set */

Lecture 6/40
Testing bits, cont.

• The mask (64) is often written in hex (0x0040), but a
constant-valued shift expression provides a clearer
indication of the bit position being tested:

if (bits & (1 << 6)) /* check to see if bit 6 is set */

• Almost all compilers will replace such constant-valued
expressions by a single constant, so using this form almost

Lecture 6/41
Testing keyboard flags using bitwise
operators

#define     FALSE        (0)   BOOL      Kybd_Flags_Changed(SHIFTS *) ;
#define     TRUE         (1)   void Display_Kybd_Flags(SHIFTS *) ;

typedef unsigned char BOOL ;   void main()
{
typedef struct SHIFTS               SHIFTS kybd ;
{
BOOL right_shift   ;         do
BOOL left_shift    ;              { /* repeat until both shift keys are pressed */
BOOL ctrl          ;              if (Kybd_Flags_Changed(&kybd))
BOOL alt           ;                          Display_Kybd_Flags(&kybd) ;
BOOL left_ctrl     ;              } while (!kybd.left_shift || !kybd.right_shift) ;
BOOL left_alt      ;         }
} SHIFTS ;

Lecture 6/42
continued ...

typedef unsigned int WORD16 ;

BOOL Kybd_Flags_Changed(SHIFTS *kybd)
{
static WORD16 old_flags = 0xFFFF ;
WORD16 new_flags ;

dosmemget(0x417, sizeof(new_flags), &new_flags) ;
if (new_flags == old_flags) return FALSE ;
old_flags = new_flags ;

kybd->right_shift        =   (new_flags   &   (1   <<   0))   !=   0   ;
kybd->left_shift         =   (new_flags   &   (1   <<   1))   !=   0   ;
kybd->ctrl               =   (new_flags   &   (1   <<   2))   !=   0   ;
kybd->alt                =   (new_flags   &   (1   <<   3))   !=   0   ;
kybd->left_alt           =   (new_flags   &   (1   <<   9))   !=   0   ;
kybd->left_ctrl          =   (new_flags   &   (1   <<   8))   !=   0   ;

return TRUE ;
}
Lecture 6/43
Setting bits

• Setting a bit to 1 is easily accomplished with
the bitwise-OR operator:

bits = bits | (1 << 7) ;     /* sets bit 7 */

b7b6b5b4b3b2b1b0   |   10000000            1b6b5b4b3b2b1b0
• This would usually be written more succinctly
as:
bits |= (1 << 7) ;        /* sets bit 7 */

Lecture 6/44
Setting bits, cont.

• Note that we don't add (+) the bit to the operand!
That only works if the current value of the target
bit in the operand is known to be 0.
• Although the phrase "set a bit to 1" suggests that
the bit was originally 0, most of the time the
current value of the bit is actually unknown.

Lecture 6/45
Clearing bits

• Clearing a bit to 0 is accomplished with the
bitwise-AND operator:

bits &= ~(1 << 7) ;   /* clears bit 7 */

(1 << 7)                   10000000
~(1 << 7)                    01111111
• Note that we don't subtract the bit from the
operand!

Lecture 6/46
Clearing bits, cont.

• When clearing bits, you have to be careful that
the mask is as wide as the operand. For
example, if bits is changed to a 32-bit data type,
the right-hand side of the assignment must also
be changed, as in:

bits &= ~(1L << 7) ; /* clears bit 7 */

Lecture 6/47
Inverting bits

• Inverting a bit (also known as toggling) is
accomplished with the bitwise-XOR operator
as in:
bits ^= (1 << 6) ;   /* flips bit 6 */

• Although adding 1 would invert the target bit, it
may also propagate a carry that would modify
more significant bits in the operand.

Lecture 6/48
Importance of Matching Operand Sizes
When ints Are 16-bits

0xFFFFFFFFL & ~(1 << 14)    FFFFBFFF (ok)
0xFFFFFFFFL & ~(1L << 14)   FFFFBFFF (ok)

0xFFFFFFFFL & ~(1 << 15)    00007FFF (error)
0xFFFFFFFFL & ~(1L << 15)   FFFF7FFF (ok)

0xFFFFFFFFL & ~(1 << 16)    FFFFFFFF (error)
0xFFFFFFFFL & ~(1L << 16)   FFFEFFFF (ok)

Lecture 6/49
Extracting bits

Bits 15 - 11   Bits 10 - 5    Bits 4 - 0
time                                Hours      Minutes       Seconds ÷ 2
Bits 15 - 11   Bits 10 - 6     Bits 5 - 0
time >> 5                           ?????        Hours         Minutes
Bits 15 - 11   Bits 10 - 6     Bits 5 - 0
(time >> 5) & 0x3F                  00000        00000         Minutes
15                                           0
minutes = (time >> 5) & 0x3F                   Minutes

Lecture 6/50
Inserting bits

Bits 15 - 11    Bits 10 - 5    Bits 4 - 0
oldtime                              Hours        Old Minutes    Seconds ÷ 2

Bits 15 - 11    Bits 10 - 5    Bits 4 - 0
newtime = oldtime & ~(0x3F << 5)     Hours          000000       Seconds ÷ 2

Bits 15 - 11    Bits 10 - 5    Bits 4 - 0
newtime |= (newmins & 0x3F) << 5     Hours        New Minutes    Seconds ÷ 2

Lecture 6/51
Automatic insertion and extraction using
structure bit fields
struct {
unsigned seconds      :5 ,   /* secs divided by 2 */
minutes      :6 ,
hours        :5 ;
} time ;
Leave the insertion
time.hours = 13 ;                (or extraction)
time.minutes = 34 ;              problems to the
time.seconds = 18 / 2 ;          compiler!

Lecture 6/52
Reserved/unused bit positions

typedef struct {
unsigned CF :1,        /*   Bit 0: Carry Flag              */
:1,    /*   Bit 1: (unused)                */
PF :1,    /*   Bit 2: Parity Flag             */
:1,    /*   Bit 3: (unused)                */
AF :1,    /*   Bit 4: Auxiliary Carry Flag    */
:1,    /*   Bit 5: (unused)                */
ZF :1,    /*   Bit 6: Zero Flag               */
SF :1,    /*   Bit 7: Sign Flag               */
TF :1,    /*   Bit 8: Trap Flag               */
IF :1,    /*   Bit 9: Interrupt Enable Flag   */
DF :1,    /*   Bit 10: Direction Flag         */
OF :1,    /*   Bit 11: Overflow Flag          */
:4 ;   /*   Bits 12-15: (unused)           */
} PSW ;
Lecture 6/53
Testing keyboard flags using structure bit
fields.

typedef struct KYBD_BITS      BOOL Kybd_Flags_Changed(SHIFTS *kybd)
{                          {
unsigned                   ...
right_shift :1,      KYBD_BITS *bits ;
left_shift :1,       ...
ctrl        :1,      bits = (KYBD_BITS *) &new_flags ;
alt         :1,      kybd->right_shift = bits->right_shift    !=   0   ;
:4,      kybd->left_shift = bits->left_shift      !=   0   ;
left_ctrl :1,        kybd->ctrl           = bits->ctrl        !=   0   ;
left_alt    :2 ;     kybd->alt            = bits->alt         !=   0   ;
} KYBD_BITS ;              kybd->left_alt       = bits->left_alt    !=   0   ;
kybd->left_ctrl      = bits->left_ctrl   !=   0   ;

return TRUE ;
}

Lecture 6/54
Manipulating bits in I/O ports

• I/O ports must be accessed using functions.

• It is often common for I/O ports to be either

• It is often common for several I/O ports to be
assigned to a single I/O address.

Lecture 6/55
one of the IBM/PC serial ports
Transmitter holding register (holds character
0  Write-Only
to be sent)
character)
Least significant byte of baud rate divisor
1
latch
1              Most significant byte of baud rate divisor latch
02F9
0              Interrupt enable register
02FA n/a   Read-Only Interrupt ID register
02FB n/a               Line control register (Bit 7 is the DLAB bit)
02FC n/a               Modem control register
02FD n/a   Read-Only Line status register
02FE n/a   Read-Only Modem status register
02FF   n/a             Reserved

Lecture 6/56
one of the IBM/PC serial ports, cont.

2F8                          2F9          2FA         2FB   2FC        2FD 2FE

-Only

DLAB=1

DLAB
Write

=1

THR             RBR          BRD                  IER          IIR   LCR   MCR          LSR         MSR

Lecture 6/57
Modifying bits in write-only I/O ports

earlier for manipulating bits can’t be used.

• Solution: Keep in memory a copy of the last
bit-pattern written to the port. Apply the read-
modify-write techniques to the memory copy,
and then write that value to the port.

Lecture 6/58
Modifying bits in write-only I/O ports

typedef struct LPT_CTRL {
unsigned
data_strobe   :1,    /* structure bit fields simplify */
initialize    :1,    /* control port. Note, however, */
select        :1,    /* we must later cast it as a byte */
enable_irq    :1,    /* because the outportb function */
/* unused /   :3 ;   /* requires a byte parameter.      */
} LPT_CTRL ;

static LPT_CTRL lpt1 = {0, 0, 0, 0, 0} ;   /* static! (and initialized to zeroes)    */
….
lpt1.data_strobe = 1 ;           /* change bit in memory copy; others remain unchanged. */
….
Byte2Port(0x3BE, (BYTE8) lpt1) ;           /* then copy data to the printer port     */

Lecture 6/59

• Sometimes multiple read-only ports assigned to
one address are distinguished by the order in

• Multiple write-only ports assigned to one address
can also be distinguished by order, or by the
value of specific bits in part of the data that is
written.

Lecture 6/60
I/O ports of the 8259 interrupt controller
in the IBM/PC

register
xxx10xxx   Write-Only    Initialization command word 1
0020
(ICW1)
xxx00xxx   Write-Only    Operation Control Word 2
xxx01xxx   Write-Only    Operation Control Word 3
Operation Control Word 1
0021
Write-Only    ICW2, ICW3, ICW4 (in order,
only just after writing ICW1)
0022-                            Reserved
003F

Lecture 6/61
I/O ports of the 8259 interrupt controller
in the IBM/PC.

0020                                  0021

ISR   ICW1     OCW2     OCW3       OCW1   ICW2     ICW3       ICW4
XXX10XXX XXX00XXX XXX01XXX          1st       2nd          3rd
Only after writing ICW1

Lecture 6/62
Exam questions

• What is overflow? Give an example.
• What is the difference between rollover and
overflow?
• Discuss floating-point vs. fixed-point.
• What is the binary representation of <decimal no.>?
• What is the binary representation of <hex no.>?
• Write the C code needed to
test/set/clear/insert/remove the following bits…
• Small problem related to bit manipulation, for
example:
– Give the integer value of 3 | 6              Lecture 6/63

```
Related docs
Other docs by cwv18084