Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
50
Добавлен:
14.04.2015
Размер:
1.37 Mб
Скачать

176

Chapter 6. Advanced Programming Techniques

 

 

Data Storage Formats

This section describes the storage formats of the data types available in the Cx51 compiler. The Cx51 compiler offers a number of basic data types to use in your C programs. The following table lists these data types along with their size requirements and value ranges.

Data Type

Bits

Bytes

Value Range

Bit

1

0 to 1

signed char

8

1

-128 to +127

unsigned char

8

1

0 to 255

Enum

8 / 16

1 or 2

-128 to +127 or -32768 to +32767

signed short

16

2

-32768 to +32767

unsigned short

16

2

0 to 65535

signed int

16

2

-32768 to +32767

unsigned int

16

2

0 to 65535

signed long

32

4

-2147483648 to 2147483647

unsigned long

32

4

0 to 4294967295

Float

32

4

±1.175494E-38 to ±3.402823E+38

data *, idata *, pdata *

8

1

0x00 to 0xFF

code*, xdata *

16

2

0x0000 to 0xFFFF

generic pointer

24

3

Memory type (1 byte); Offset (2 bytes) 0 to 0xFFFF

Other data types, like structures and unions, may contain scalars from this table. All elements of these data types are allocated sequentially and are byte-aligned

6

due to the 8-bit architecture of the 8051 family.

 

Bit Variables

Scalars of type bit are stored using a single bit. Pointers to bits and arrays of bits are not allowed. Bit objects are always located in the bit-addressable internal memory of the 8051 CPU. The BL51 Linker/Locator overlays bit objects if possible.

Keil Software — Cx51 Compiler User’s Guide

177

 

 

Signed and Unsigned Characters,

Pointers to data, idata, and pdata

Scalars of type char are stored in a single byte (8 bits). Memory-specific pointers that reference data, idata, and pdata are also stored using a single byte (8 bits). If an enum can be represented with an 8 bit value, the enum is also stored in a single byte.

Signed and Unsigned Integers,

Enumerations, Pointers to xdata and code

Scalars of type int, short, and enum, and memory-specific pointers that reference xdata or code are all stored using two bytes (16 bits). The high-order byte is stored first, followed by the low-order byte. For example, an integer value of 0x1234 is stored in memory as follows:

Address

+0

+1

Contents

0x12

0x34

 

 

 

Signed and Unsigned Long Integers

 

 

 

Scalars of type long are stored using four bytes (32 bits). The bytes are stored in

 

high to low order. For example, the long value 0x12345678 is stored in memory

6

as follows:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Address

+0

+1

+2

+3

 

 

 

 

 

 

 

 

 

Contents

0x12

0x34

0x56

0x78

 

 

 

 

 

 

 

 

 

178

Chapter 6. Advanced Programming Techniques

 

 

Generic and Far Pointers

Generic pointers have no declared explicit memory type. They may point to any memory area on the 8051. These pointers are stored using three bytes (24 bits). The first byte contains a value that indicates the memory area or memory type.

The remaining two bytes contain the address offset with the high-order byte first. The following memory format is used:

Address

+0

+1

+2

Contents

Memory Type

Offset; High-Order Byte

Offset; Low-Order Byte

 

 

 

 

Depending on the compiler version that you are using, the memory type byte has the following values:

Memory Type

idata / data / bdata

Xdata

pdata

code

C51 Compiler (8051 devices)

0x00

0x01

0xFE

0xFF

CX51 Compiler (Philips 80C51MX)

0x7F

0x00

0x00

0x80

 

 

 

 

 

The Philips 80C51MX architecture supports new CPU instructions that operate on a universal pointer. Universal pointers are identical with Cx51 generic pointers.

The format of the generic pointers is also used for pointers with the memory type far. Therefore, any other memory type values are used to address far memory space.

 

 

The following example shows the memory storage of a generic pointer (on the

6

 

C51 compiler) that references address 0x1234 in the xdata memory area.

 

 

 

 

 

 

 

Address

+0

+1

+2

 

 

 

Contents

0x01

0x12

0x34

 

 

 

 

 

 

 

 

 

Keil Software — Cx51 Compiler User’s Guide

179

 

 

Floating-point Numbers

Scalars of type float are stored using four bytes (32-bits). The format used follows the IEEE-754 standard.

A floating-point number is expressed as the product of two parts: the mantissa and a power of two. For example:

±mantissa × 2exponent

The mantissa represents the actual binary digits of the floating-point number.

The power of two is represented by the exponent. The stored form of the exponent is an 8-bit value from 0 to 255. The actual value of the exponent is calculated by subtracting 127 from the stored value (0 to 255) giving a range of – 127 to +128.

The mantissa is a 24-bit value (representing about seven decimal digits) whose most significant bit (MSB) is always 1 and is, therefore, not stored. There is also a sign bit that indicates whether the floating-point number is positive or negative.

Floating-point numbers are stored on byte boundaries in the following format:

Address

+0

+1

+2

+3

 

 

Contents

SEEE EEEE

EMMM MMMM

MMMM MMMM

MMMM MMMM

 

 

where:

 

 

 

 

 

6

S

represents the sign bit where 1 is negative and 0 is positive.

E

is the exponent with an offset of 127.

 

 

 

 

 

 

M

is the 24-bit mantissa (stored in 23 bits).

 

 

 

Zero is a special value denoted with an exponent field of 0 and a mantissa of 0.

180 Chapter 6. Advanced Programming Techniques

The floating-point number -12.5 is stored as a hexadecimal value of 0xC1480000. In memory, this value appears as follows:

Address

+0

+1

+2

+3

Contents

0xC1

0x48

0x00

0x00

 

 

 

 

 

It is fairly simple to convert floating-point numbers to and from their hexadecimal storage equivalents. The following example demonstrates how this is done for the value -12.5 shown above.

The floating-point storage representation is not an intuitive format. To convert this to a floating-point number, the bits must be separated as specified in the floating-point number storage format table shown above. For example:

Address

+0

+1

+2

+3

Format

SEEEEEEE

EMMMMMMM

MMMMMMMM

MMMMMMMM

Binary

11000001

01001000

00000000

00000000

Hex

00

00

48

C1

 

 

 

 

 

From this illustration, you can determine the following information:

The sign bit is 1, indicating a negative number.

The exponent value is 10000010 binary or 130 decimal. Subtracting 127 from 130 leaves 3, which is the actual exponent.

6

The mantissa appears as the following binary number:

10010000000000000000000

 

Keil Software — Cx51 Compiler User’s Guide

181

 

 

There is an understood binary point at the left of the mantissa that is always preceded by a 1. This digit is omitted from the stored form of the floating-point number. Adding 1 and the binary point to the beginning of the mantissa gives the following value:

1.10010000000000000000000

Next, adjust the mantissa for the exponent. A negative exponent moves the decimal point to the left. A positive exponent moves the decimal point to the right. Because the exponent is three, the mantissa is adjusted as follows:

1100.10000000000000000000

The result is a binary floating-point number. Binary digits to the left of the decimal point represent the power of two corresponding to their position. For example, 1100 represents (1 × 23) + (1 × 22) + (0 × 21) + (0 × 20), which is 12.

Binary digits to the right of the decimal point also represent the power of two

corresponding to their position. However, the powers are negative. For example, .100… represents (1 × 2-1) + (0 × 2-2) + (0 × 2-3) + … which equals

.5.

The sum of these values is 12.5. Because the sign bit was set, this number should be negative. So, the hexadecimal value 0xC1480000 is -12.5.

6

182

Chapter 6. Advanced Programming Techniques

 

 

Floating-point Errors

The 8051 does not contain an interrupt vector to trap floating-point errors; therefore, your software must appropriately respond to these error conditions.

In addition to the normal floating-point values, a floating-point number may contain a binary error value. These values are defined as a part of the IEEE standard and are used whenever an error occurs during normal processing of floating-point operations. Your code should check for possible arithmetic errors at the end of each floating-point operation.

Name

Value

Meaning

NaN

0xFFFFFFF

Not a number

+INF

0x7F80000

Positive infinity (positive overflow)

-INF

0xFF80000

Negative infinity (negative overflow)

NOTE

The Cx51 library function _chkfloat_ lets you quickly check floating-point status.

You can use the following union to store floating-point values.

 

 

union f

{

 

 

 

float

f;

/* Floating-point value */

 

 

unsigned long ul;

/* Unsigned long value */

 

 

};

 

 

6

 

 

 

This union contains a float and an unsigned long in order to perform floating-

 

point math operations and to respond to the IEEE error states.

 

 

 

 

 

Keil Software — Cx51 Compiler User’s Guide

183

 

 

For example:

#define

NaN

0xFFFFFFFF

/* Not a number (error) */

#define

plusINF

0x7F800000

/* Positive overflow

*/

#define

minusINF

0xFF800000

/* Negative overflow

*/

union f {

 

 

 

float

 

f;

/* Floating-point value */

unsigned long

ul;

/* Unsigned long value */

};

 

 

 

 

void main (void)

{

 

 

float a, b;

 

 

 

union f x;

 

 

 

x.f = a * b;

if (x.ul == NaN || x.ul == plusINF || x.ul == minusINF) { /* handle the error */

}

else {

/* result is correct */

}

}

6

Соседние файлы в папке HLP