#Introduction
The C28x is a 16-bit addressable CPU. That is, each unique address identifies
16 bits of data. 16-bit and 32-bit reads and writes are easily achieved via MOV
(16-bit) and MOVL (32-bit) instructions. To access 8-bit data, special MOVB
instructions are used. These instructions can access either the LSB or the MSB
of the 16-bit word.
This article describes how these special instructions can be accessed when
writing code in C or C++.
#Other Resources
* [Code Generation Tools Wiki](https://processors.wiki.ti.com/index.php/Category:Compiler)
* [TMS320C28x CPU and Instruction Set Reference Guide (spru430)](https://www.ti.com/lit/pdf/spru430)
* [TMS320C28x Optimizing C/C++ Compiler User's Guide (spru514)](https://www.ti.com/lit/pdf/spru514)
* [Reading and Writing Binary Files on Targets With More Than 8-Bit Chars (spra757)](https://www.ti.com/lit/an/spra757/spra757.pdf)
#Byte Accesses With the C28x Compiler
The TMS320C28x byte is 16 bits. By ANSI/ISO C definition, the sizeof operator
yields the number of bytes required to store an object. ANSI/ISO further
stipulates that when sizeof is applied to char, the result is 1. Since the
TMS320C28x char is 16 bits (to make it separately addressable), a byte is also
16 bits.
This yields results you may not expect; for example, size of (int) == 1 (not 2).
It should also be noted that contrary to common usage, a byte is not defined as
8 bits. A byte is defined as the unit of data capable of holding a single
character on any given machine. Hence, if the term "byte" is used on C2000 it
refers to 16 bits. In summary: TMS320C28x bytes and words are equivalent (16 bits).
To access data in increments of 8 bits, use the __byte intrinsic described in
the [TMS320C28x Optimizing C/C++ Compiler User's Guide (spru514)](https://www.ti.com/lit/pdf/spru514).
#Using the __byte Intrinsic
##What are Intrinsics?
The C28x compiler recognizes a number of intrinsic operators. Intrinsics allow
you to express the meaning of certain assembly statements that would otherwise
be cumbersome or inexpressible in C/C++. Intrinsics are used like functions;
you can use C/C++ variables with these intrinsics, just as you would with any normal function.
The intrinsics are specified with two leading underscores, and are accessed by
calling them as you do a function. Available intrinsics are documented in the
[TMS320C28x Optimizing C/C++ Compiler User's Guide (spru514)](https://www.ti.com/lit/pdf/spru514).
In addition, consult the release notes for your compiler to see if new
intrinsics have been added since the documentation was last updated.
##The __byte Intrinsic
Prototype int &__byte(int *array, unsigned int byte_index);
Generated Assembly:
* If the operation is a write: MOVB array[byte_index].LSB, src
* If the operation is a read: MOVB dst, array[byte_index].LSB
##Example 1
The following example shows how the compiler will translate the __byte
intrinsic to a MOVB.LSB operation.
```c
//
// Example code to show the use of the __byte C28x Compiler intrinsic
//
int16 MyArray[20];
int16 Val;
int16 Read1;
int16 Read2;
int16 Read3;
int16 Read4;
void main(void)
{
// Note: - means value was unchanged
// from the previous state
//
__byte(MyArray,0) = 0x00; // MyArray[0] = 0x--00
__byte(MyArray,1) = 0x11; // MyArray[0] = 0x1100
__byte(MyArray,2) = 0x22; // MyArray[1] = 0x--22
__byte(MyArray,3) = 0x33; // MyArray[1] = 0x3322
__byte(MyArray,4) = 0x44; // MyArray[2] = 0x--44
__byte(MyArray,5) = 0x55; // MyArray[2] = 0x5544
__byte(&Val,0) = 0x66; // Val1 = 0x--66
__byte(&Val,1) = 0x77; // Val1 = 0x7766
Read1 = __byte(MyArray,2); // Read1 = 0x0022 (note: clears upper byte)
Read2 = __byte(MyArray,5); // Read2 = 0x0055 (note: clears upper byte)
Read3 = __byte(MyArray,4); // Read3 = 0x0044 (note: clears upper byte)
Read4 = __byte(MyArray,5); // Read4 = 0x0055 (note: clears upper byte)
...
```
Execution of this code will change memory contents as shown below:
![](./images/example1-movb.jpg)
##Example 2
The following example illustrates how __byte can be used on the left-hand side
to set values. This is the reason it returns a reference.
```c
#include
int array[3] = { 0xaaaa, 0xbbbb, 0xcccc };
void main()
{
int i;
__byte(array, 0) = 0;
for (i=0;i<3;i++)
printf("%x\n", array[i]);
for (i=0;i<6;i++)
printf("%x\n", __mov_byte(array, i));
}
```
#Byte Addressing Modes
For the most part you do not need to worry about the addressing modes when using
the intrinsics. It is useful to understand if you are looking at the generated
assembly code or writing assembly code from scratch.
Example 1 shown in the previous section generates the following assembly code:
![](./images/addressing-movb.jpg)
The instructions generated by the compiler follow the byte addressing mode rules
shown below. More detail and additional forms of MOVB can be found in the
[TMS320C28x CPU and Instruction Set Reference Guide (spru430)](https://www.ti.com/lit/pdf/spru430)
```c
Instruction: MOVB AX.LSB, loc16
Offset: AR0, AR1 or 3-bit value
if( loc16 == *+XARn[offset] )
if( offset == even )
AX.LSB = [loc16].LSB;
AX.MSB = 0x00;
if( offset == odd )
AX.LSB = [loc16].MSB;
AX.MSB = 0x00;
else
AX.LSB = [loc16].LSB;
AX.MSB = 0x00;
```
```c
Instruction: MOVB loc16,AX.LSB
Offset: AR0, AR1 or 3-bit value
if( loc16 == *+XARn[offset] )
if( offset == even )
[loc16].LSB = AX.LSB
[loc16].MSB = untouched;
if( offset == odd )
[loc16].LSB = untouched;
[loc16].MSB = AX.LSB;
else
[loc16].LSB = AX.LSB;
[loc16].MSB = untouched;
```
#Frequently Asked Questions
**Q: The prototype for \_\_byte is &\_\_byte(int * array, unsigned int byte_index). Is the "&" a typo?**
**A:** It is not a typo, the __byte intrinsic returns a C++-style reference, even in C mode.
**Q: What is the difference between \_\_byte and \_\_mov_byte**
**A:** The \_\_byte intrinsic is preferred over __mov_byte.
\_\_mov\_byte is much older, and was implemented before the compiler could support
an intrinsic that returns a reference. To maintain backward compatibility,
\_\_mov\_byte was left as-is, and a new intrinsic \(\_\_byte\) was added which returns
the reference. There is nothing you can do with \_\_mov\_byte that you can't do with \_\_byte.