Lecture 6 Data Representation and Bit Manipulation in C

Document Sample
scope of work template
							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
                Hexadecimal numbers

• 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
       10011                  (The right answer!)
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
  (adjectives).

• 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
  never generates any additional code.




                                                                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
  read-only or write-only.

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


                                                   Lecture 6/55
          I/O addresses used by
       one of the IBM/PC serial ports
Addr. DLAB Restriction Description
                       Transmitter holding register (holds character
        0  Write-Only
                       to be sent)
                       Receiver buffer register (contains the received
02F8    0  Read-Only
                       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
          I/O Addresses used by
   one of the IBM/PC serial ports, cont.


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




                                                        Read-Only




                                                                                              Read-Only
                                                                                 Read-Only
      -Only




                                   DLAB=1
              Read-Only

                          DLAB
Write




                              =1




THR             RBR          BRD                  IER          IIR   LCR   MCR          LSR         MSR



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


• The read-modify-write techniques presented
  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 */
           auto_linefeed :1,    /* access to the printer's packed */
           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
      Sequential access to I/O ports

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

• 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

  Addr.     Data     Restriction   Description
                     Read-Only     Interrupt request or in-service
                                   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
                                   (Interrupt mask register)
  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