Explanation of byte alignment issues

Source: Internet
Author: User

1. ExplanationBYTE (byte) is a unit of measurement in which computer information technology is used to measure storage capacity and transmission capacity, a byte equals a 8-bit binary number, and in UTF-8 encoding an English character is equal to one byte. Bytes are arranged spatially according to certain rules and are byte-aligned. The memory space in modern computers is divided by Byte, in theory it seems that access to any type of variable can start from any address, but the reality is that when accessing a particular type of variable, it is often accessed at a specific memory address, which requires all types of data to be spatially arranged according to certain rules, Instead of sequentially one by one emissions, that's the alignment.
2. Function and ReasonThe processing of storage space varies greatly with each hardware platform. Some platforms can only access certain types of data from certain specific addresses. For example, some architectures have an error when accessing a variable that is not aligned, so programming must ensure byte alignment in this architecture. Other platforms may not have this, but the most common is the loss of access efficiency if the data storage is not aligned according to their platform requirements. For example, some platforms read each time from the even address, if an int (assuming 32-bit system) if the location of the place where the even address begins, then a read cycle can be read out of the 32bit, and if it is stored at the beginning of the odd address, it takes 2 read cycles, The 32bit data can be obtained by piecing together the high and low bytes of the two read-out results.


Example
For example, under a 32-bit CPU, assuming an integer variable has an address of 0x00000004, it is naturally aligned. Assuming that the address of the integer variable above is not naturally aligned, such as 0x00000002, then the CPU needs to access two memory if it takes its value, the first time to take a short from 0x00000002-0x00000003 and the second fetch from 0x00000004-0x A short of 00000005 then combined to get the desired data, if the variable is on the 0x00000003 address, then access to three memory, the first is char, the second is short, the third is char, and then combined to get the integer data. If the variable is in the natural alignment position, the data can be fetched once. Some systems have strict alignment requirements, such as SPARC systems, where an error occurs if an unaligned data is taken, as an example:

Char Ch[8];
Char *p = &ch[1];
int i = * (int *) p;

The runtime will report segment error, and there will be no errors on the x86, just a decrease in efficiency.
3. Correctly handle byte alignment for a standard data type, its address is as long as it is an integer multiple of its length, and non-standard data types are aligned according to the following principle:

Arrays: aligned According to the basic data type, the first one is aligned with the nature of the back.
struct: Each data type in the struct is aligned. (in each compiled environment, an aligned value is specified by default, and each struct has a self-aligning value that is the dimension value of the longest-occupied field in all fields in the structure body).
For example, there is a structure like this:
struct Taga
{
Char CNum;
int iage;
Char ccount[5];
}A1;
struct Taga A2;
This struct int variable takes up the longest byte (the array cannot be counted by the base type, char ccount[5] or 1)---4 bytes, so the struct's self-aligning value is 4. When the program allocates memory, it allocates memory from the default specified alignment value and 2 values of the struct's own alignment value, which is our sizeof (A2) will get a length of 16 instead of 9.
In the VC default value is 8, the default value in Keil is 1, so A1 in the VC allocation of memory is selected is min (8,4), in the Keil selected is min (1,4) to allocate A1 this structure. Let's say the length is L.
When compiling, the first choice of the structure of the first address is not random, first in memory to be able to be within the structure of the longest field divisible by the address
(VC specific to this example is a multiple of 4 address, Keil is the address of a multiple of 2), and then began to sequence the field, the structure of the front of the fields in front of the structure near the address of the first row cnum, then iage, the last row ccount[5]. When there are rules, the basic data type length of less than equal to the L field must be in the address can be divisible by the length of the non-contiguous portion of the part with empty bytes (specifically here iage this field is 4, must be ranked in the address can be divisible by 4, but the first address is divisible by 4, cnum only need 1 bytes, This time in the back of the Cnum need to fill 3 empty bytes, these empty bytes is a waste of memory, but in exchange for some efficiency of the memory is worth it, for the basic data type length greater than L must be ranked in the address can be divisible by L of the non-contiguous parts with empty bytes to fill up (specifically here, If the l=1 in the Keil environment, the integer field iage accounted for 2 bytes, so the Keil line can be divisible by 1 anywhere on it), and finally after all the fields, if the total number of bytes from the end of the first address to the last field is not an integer multiple of L, you need to use empty bytes.


This is all the rules for byte alignment.
It is also necessary to add that although the compilation environment has an alignment value by default, you can
#pragma pack (2)
struct A
{
Char ch;
int i;
Short St;
Char ch1[3];
}ta;
#pragma Pack 2 preprocessing commands are reset, #pragma pack (x) indicates that the following section defaults to x when allocating memory
#pragma pack represents the Undo #pragma pack (x) operation.
4, graphic explanation 1, fully consider four byte alignment, can save storage space
typedef struct tagaaa{
Char name[10];
Long Sno;
char sex;
float score[4];
}AAA;
typedef struct tagbbb{
Char name[10];
char sex;
Long Sno;
float score[4];
}BBB;
Under the VC, debugging, it can be easily seen, AAA accounted for the storage space of 36,BBB accounted for 32 of the storage space. The reason is simple, in the case of four-byte alignment, the allocation of storage space in four bytes, if not enough, will be automatically replenished, this allocation is insufficient to hold the following variable, the space will be redistributed.
Aaa:
|name[0]|name[1]|name[2]|name[3]|
------------------------------------
|name[4]|name[5]|name[6]|name[7]|
------------------------------------
|name[8]|name[9]|                   | |
----------because the remaining two bytes are not enough to hold Sno (Long is four bytes), it is redistributed
------------------------------------
| Sno |
----------A long variable is four bytes, 32bits
------------------------------------
|sex | Auto-Fill |
----------the remaining three bytes of space, not enough to replay a float variable, so reassign
------------------------------------
| Score[0] |
------------------------------------
| ..........                                        |
------------------------------------
| SCORE[3] |
------------------------------------
This makes it easy to calculate that AAA accounts for 36 bytes, and the same is easier to calculate that BBB accounts for 32 bytes of space.

2, byte to its case, can be more efficient access
Suppose the data for a struct is stored as follows:
-----------------------------------------------------
|       12 |        34 |        56 |   78 | -----------(A)
-----------------------------------------------------
-----------------------------------------------------
|       XX |        YY |         12 |   34 | -----------(B)
-----------------------------------------------------
|        56 |       78 |         XX | YY |
In a case, a one-time reading of the data is successful, but, in the case of B, you need to read the data two times, thus, you can see the difference in efficiency.
In general, the minimum principle of byte-aligned compliance system bytes versus the required number of aligned bytes is that the assumption requires eight-byte alignment, but the system is a 32-bit system, followed by 4-byte alignment. When four-byte alignment, the local is aligned by 2 bytes, such as:
struct TAGAAA
{
Char A;
Short B;
char c;
}AAA;
The structure occupies a space of 8 bytes instead of 4 bytes, because:
-----------------------------------
|          A |             | B |
-----------------------------------
|                                      C | |
Instead of:
------------------------------------
|          A |        B | C |
------------------------------------
The reason is that the local will be aligned with 2 bytes.

***********************************************
5, when you need to set the alignment in the design of the communication protocol under different CPUs, or the structure of the register when writing a hardware driver two places need to be aligned by one byte. Even if it seems to be naturally aligned, it should be aligned so that different compiler-generated code is not the same.


6, for byte alignment, we in the programming how to consider

If you want to consider saving space when programming, then we only need to assume that the first address of the structure is 0, then the various variables are arranged according to the above principles, the basic principle is to make the variables in the structure from small to large declaration, as far as possible to reduce the middle of the filling space. There is another way to make space for the efficiency of time, we show the space to fill the alignment, for example: there is a use of space-time approach is to explicitly insert reserved members:
struct A
{
Char A;
Char reserved[3]; Use space to change time
int b;
};
The reserved member has no meaning to our program, it just fills the space to achieve byte alignment, and of course even without this member The compiler will also give us auto-fill the alignment, we add it just as a reminder to show.
7, the byte alignment may bring the hidden trouble code in the concern about the alignment, many are implicit. For example, when forcing type conversions. For example:
unsigned int i = 0x12345678;
unsigned char *p = NULL;
unsigned short *p1 = NULL;
p=&i;
*p=0x00;
p1= (unsigned short*) (p+1);
*p1=0x0000;
The last two lines of code, from the odd boundary to access the unsigned short variable, clearly do not conform to the alignment rules. On X86, similar operations only affect efficiency, but on MIPS or SPARC, it can be an error because they require that the bytes be aligned.


8. How to find problems with byte alignment if an alignment or assignment problem occurs first view
1. Alignment values set by the compiler
2. See if the system itself supports non-aligned access
3. If the support depends on whether the alignment is set or not, then if there is no access, you need to add some special decorations to flag its special access operation.

Explanation of byte alignment issues

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.