In this video, we will discuss how data is ordered in memory. In the previous videos, we have learned about the data path between memory and CPU for both code and data. Information gets loaded into the CPU and then stored back to memory once we are done processing. To make this most efficient for CPU execution, we align our data accesses. To make this most efficient for memory storage, we would pack our data using unaligned accesses. We have yet to discuss how we actually order our data in memory. Byte order is the last characterization to memory storage that we need to talk about. When you attempt to read or write one byte of memory, there is no confusion with its byte order. Since memory is byte addressable and you are only interacting with a single byte, it gets read and written to that exact location you specified. However, when we begin to start creating multi-byte data types, you should ask yourself which bytes should come first in memory? The most significant byte (MSB) or the least significant byte (LSB)? The term Endianness describes byte order on a computer system. There are two types of Endianness; big endian or little endian. Each of these store bytes in a certain order for half word or larger data types starting at the same address. Byte order does not affect the amount of memory a piece of data will allocate nor the alignment. Big endian is a byte order that specifies that the most significant byte gets stored at the first address or at the lowest address in memory. That will be followed by the next most significant byte. The least significant byte is placed at the highest address. Let's look an example for a word. If we add a word that was initialized to hex ABCD1234 and assume this word was stored at address 0, AB would be our most significant byte and that would go first in memory, starting at address zero. This would be followed by CD1234 in the next three byte locations. Little endian is the exact reverse of big endian. The order specifies that the least significant byte comes first in memory or stored at the lowest address. The most significant byte would be stored at the highest address. Given the same example of a 32-bit word, initialized to hex ABCD1234, we would see that the least significant byte, 34, gets stored in the address zero. AB, the most significant byte, would be stored at hex three. Endianness does not affect things like order of elements in an array, unions or structures. Endianness only affects the byte order of individual items. An example for an array of half words would be the first item of array would still be placed at the first location in memory followed by the second and the third and so on. The Endianness will only affect the byte order within each of these items themselves. The LSB and MSB would just flip positions on each half word, until you switch from big endian to little endian. Endianness applies to both code and data memory and some architectures that cannot be changed. They are designed around one type. However, more modern designs have begun to create systems that can be configured for either. ARM is an example of this, ARM originally was a big endian architecture that turned into being configurable. The architecture allows data memory to be configurable, but by default, works as little endian. Code memory on a cortex end processor are set to little endian exclusively and it's not configurable. If you are interested in reconfiguring your ARM core data memory to be big endian, you would have to reset the processor to do so, as you cannot reconfigure it on the fly. Inside our ARM cortex micro-controllers there is a memory region on the internal private peripheral bus called the system control space. Inside this space is a register referred to as the Application Interrupt and Reset Control Register or the AIRCR. This register contains a bit that allows us to set the endianness for data memory. By default, it is zero for little endian, but it can be set to big endian. Endianness can be trouble if you were trying to write a portable application across multiple architectures or trying to interface two different architectures together via an external communication bus. If we had two embedded systems communicating and streaming bytes to one another, two systems could be running the same software; one big endian and one little endian. And let's say that the transmitter is configured for big endian and it begins to transmit out the MSB first. The second embedded system is a little endian, running the same code. And then they want to interpret the first byte as the least significant byte. In such a case, you may need to perform a software operation called a swap in order to do a data reorder. A byte swap is a simple software example where we can take a pointer to a data type with some endianness and switch this data to the opposite endianness; big to little or little to big. In order to do this, you would need to know the size of the item you're trying to switch endianness for. In this example, we have a 32-bit word. We'll write a function that uses a temporary byte for an intermediate storage location as we swap MSB and LSB. We will have to do this twice; one for the MSB and LSB and again for the inside bytes. After running this function on our test data from earlier, you can see that ABCD1234 gets reordered in memory to 3412CDAB. Utilizing different memories on a micro-controller is a very complex process behind the scenes. There are multiple memory types, different code and data segments, multiple interfaces and different alignments and byte ordering. An embedded engineer must be familiar with all of these to most highly optimize their use of an embedded platform.