677 - detailed explanation of large end mode and small end mode

Keywords: C

1. What is the core of big end and small end?

The large end mode and the small end mode are two modes corresponding to the actual byte order and the stored address order, which are summarized as follows:
Big end mode: low address corresponds to high byte
Small end mode: low address corresponds to low byte

No matter in the big end or small end mode, when we read and store data, we must read or write from the low address of the memory to the high address in turn.

2. What is storage order?

For example, we define an array, char array[5] = {0,1,2,3,4};
The memory distribution of array storage is as follows:

Whether writing or reading, we can find the element content we want as long as we use this first address. From this point of view, when storing, we store 0, 1, 2, 3 and 4 in turn. When reading, we also start from array[0] and read 0, 1, 2, 3 and 4 in turn.

3. Sending data from big end mode to small end mode

With the premise that data is read or stored from low to high according to bytes, the following examples illustrate the difference between the large end and the small end.
Suppose A wants to send four bytes of data to B,
The storage mode of A is large end mode, and the storage mode of B is small end mode.
The memory distribution of A's storage 1234 is shown in the figure below

Because a stores in the big end mode and according to the law that the low address corresponds to the high byte, a sends the value int Value_A = 0x12345678.

Value_A will send the low address to B in turn. Why is the low address here? Because the start of sending is to read the data. The read data must be read from the low address. Then B receives the values 0x12, 0x34, 0x560 and x78 in turn.

B stores the received values in the memory as shown in the figure below. During storage, they are also stored from low address to high address

B after receiving, you need to read the value in memory to value_ From B, then value_ What is the value of B?
B is stored according to the small end mode, and the low byte corresponding to the low address, then int Value_B = 0x78563412
Many people here may have questions? Isn't it that the reading is from the low address to the high address? Why are the read values different for the same storage?

This is the key. After reading 0x12, the mode set by the system is that the low address corresponds to the low byte, and our Value_B is an int type and four bytes of data. The data displayed in front of us must be in descending order from left to right bytes, so 0x12 is placed in the lowest byte, as shown in the following figure.

I.e. Value_B = 0x78563412;
Value_A is not equal to Value_B. This is why we must confirm the byte order during network communication. We must ensure that the byte orders of a and B are the same. If they are different, we need to use the byte order conversion function.

4. Byte order conversion function

1,htons hold unsigned short Type conversion from host sequence to network sequence( host to network short)
2,htonl hold unsigned long Type conversion from host sequence to network sequence( host to network long)
3,ntohs hold unsigned short Type conversion from network order to host order(network to host short)
4,ntohl hold unsigned long Type conversion from network order to host order(network to host long)

The host byte order is generally small end (most and a few are also large end storage), and the network byte order is large end storage.

Small end to large end method 1

UINT32  LE2BE(UINT8* dat, UINT8   len)
{
	UINT32  temp = 0, fact = 1;
	UINT8     i = 0;
	for (i = 0; i < len; i++)
	{
		temp += dat[i] * fact;
		fact *= 256;
	}
	return temp;
}

What does this program mean?
Let's give an example.
In the above case, if B wants to send int test_B = 0x12345678 to A, B's storage is the small end mode, and B wants to correctly send 0x12345678 to A, then A will not receive 0x12345678 according to the above sending and receiving.
A will receive 0x78, 0x56, 0x34 and 0x12 in turn. Without conversion, the low address corresponds to the high byte, and test_A = 0x78563412.
Here, you need to convert according to the above.
The intent of the above procedure is as follows:

temp = 0x78*1 + 0x56*256 + 0x34 * 256*256 + 0x12*256*256*256
     = 120+22016+3407872+301989888
     = 305419896
     = 0x12345678

After conversion, the value obtained by A is the temp value, that is, the value transmitted by B.
See here, even if the big end and small end problems are explained clearly, the core of the problem is actually a byte order and a storage order.

Small end to large end method 2

#include <stdio.h>

union endian//Consortium (Consortium)
{
	char a[4];
	int b;
}big;

//Convert int type data from small endian to large endian
int big_endian(int n)
{
	char temp;
	big.b = n;
	//The 1st byte is exchanged with the 4th byte
	temp = big.a[0];
	big.a[0] = big.a[3];
	big.a[3] = temp;

	//The 2nd byte is exchanged with the 3rd byte
	temp = big.a[1];
	big.a[1] = big.a[2];
	big.a[2] = temp;
	return big.b;
}

void main()
{
	int n = 0x12345678;
	printf("Small end sequence:%#x\n", n);
	n = big_endian(n);
	printf("Large end sequence:%#x\n", n);
}

Small end to large end method 3

#include <stdio.h>
 
//Convert int type data from small endian to large endian
void main()
{
	int n=0x12345678;
	char *p=(char *)&n;
	printf("Small end sequence:%#x\n",n);
	n=(*p)<<24|(*(p+1))<<16|(*(p+2))<<8|(*(p+3));
	printf("Large end sequence:%#x\n",n);
}

How to determine the byte order of the machine 1

#include <stdio.h>
int main (void)
{
	union
	{
		short i;
		char a[2];
	}u;
	u.a[0] = 0x11;
	u.a[1] = 0x22;
	printf ("0x%x\n", u.i);  //0x2211 is the small end and 0x1122 is the large end
	return 0;
}
Output results:
0x2211

The space occupied by Union data is equal to the space occupied by its largest member. Access to union members starts at an offset of 0 relative to the base address of the union, that is, access to any variable of the Union starts from the first address of the union.
Federation is a data type that stores different types of data in the same storage space. The addresses of these stores are the same, the memory of different storage areas in the Federation is overlapped, and any other one will be affected if any other is modified.

How to determine the byte order of the machine 2

How to determine the byte order of the machine 3

Posted by fullyloaded on Wed, 13 Oct 2021 10:11:09 -0700