The byte order of glibc

Source: Internet
Author: User
Tags htons

We know that the byte order is divided into big-Endian and little-endian. Large-end machines have the IBM architecture, while Intel architecture hosts use small-end machines. What we need to know is that in network programming, the byte order is large, so we need to convert the host's byte order to the network's byte order. Here, we need to explain why the network byte sequence needs to be large. The main feature of the big end is that we write a certain number of hexadecimal forms (from left to right: high byte-> low byte) the storage format is the same as that in the memory (from left to right: Low address-> high address), and the appearance is the same, so the network byte sequence is easy to understand (personal opinion, haha ), we can see from the brackets.

(Appendix: in network transmission, the big-Endian sequence is used.0x0a0b0c0dThe transmission order is0a 0b 0C 0d (starting from the low address during transmission)Therefore, big-Endian serves as the network byte order and little-Endian serves as the host byte order. Why does x86 storage use little-Endian? At first I thought it was very convenient for bit operations, especially displacement operations, but it was also convenient for big-Endian, it is nothing more than the difference between the left shift and the right shift, but the advantage of little-Endian is that the storage location does not need to be changed when the unsigned char/short/INT/long type is converted. For example, short a = 0x1234; Small-byte Host Storage memory is as follows:

Add add + 1

34, 12
)

After int B = (INT) a, B memory storage is:

Add add + 3

34, 12, 00, 00

As you can know, the type conversion is very simple, just add 0x0000 to the end)

 

 

The large byte order is the most important byte (high, also known as the most significance of bytes) stored in the low address (front address, that is, front), high front, that is, the form of our writing.

For example, 0x12345678.

If a large end is used, it is stored in the memory as follows:

Add add + 3

12, 34, 56, 78

 

The format is the same as ours.

If you use a small terminal, it will be stored as follows:

Add add + 3

78, 56, 34, 12

 

Summary: Large ends (in bytes) are in front (low addresses), and small ends are in front (low addresses)

 

 

With the above discussion, this article discusses in detail the implementation mechanism of the byte order below glibc. The library files involved in this article include:

/Usr/include/bits/endian. h

/Usr/include/endian. h

/Usr/include/bits/byteswap. h

/Usr/include/byteswap. h

 

 

//////////////////////////////////////// //////////////////////////////////////// ////

/Usr/include/bits/endian. h

/* This file defines '_ byte_order' For the participates machine .*/

This file mainly defines the machine's byte order. For example, for Intel i386

1/* i386 is little-Endian .*/
2
3 # ifndef _ endian_h
4 # error "never use <bits/endian. h> directly; include <endian. h> instead ."
5 # endif

// The preceding pre-compiled commands are used to prevent direct inclusion of bits/endian. h header file, because macro _ endian_h is in/usr/include/endian. h defined, if it does not contain/usr/include/endian. h file, the corresponding macro is not defined, and a pre-compilation error is generated through # error, that is, the interface provided by the system to the outside can only be

The include/endian. h header file has nothing to do with machines, while the bits/endian. h file is related to specific machines. This improves the portability of the program, because the system provides the header file include/endian. H that is not related to the system.

6
7 # DEFINE _ byte_order _ little_endian

//////////////////////////////////////// //////////////////////////////////////// ////

/// Usr/include/endian. h file content is as follows:
19 # ifndef _ endian_h
20 # DEFINE _ endian_h 1
21
22 # include <features. h>
23
24/* Definitions for byte order, according to significance of bytes (high byte ),
25 from low addresses to high addresses. The value is what you get
26 putting '4' in the most significant byte, '3' in the second most
27 significant byte, '2' In the second least significant byte, and '1'
28 in the least significant byte, and then writing down one digit
29 each byte, starting with the byte at the lowest address at the left,
30 and proceeding to the byte with the highest address at the right .*/
31
32 # DEFINE _ little_endian 1234
33 # DEFINE _ big_endian 4321
34 # DEFINE _ pdp_endian 3412
35
36/* this file defines '_ byte_order' for the particle machine .*/
37 # include <bits/endian. h> // The _ endian_h macro is defined before, so this file can contain
38
39/* some machines may need to use a different endianness for Floating Point
40 values .*/
41 # ifndef _ float_word_order
42 # DEFINE _ float_word_order _ byte_order
43 # endif
44
45 # ifdef _ use_bsd
46 # define little_endian _ little_endian
47 # define big_endian _ big_endian
48 # define pdp_endian _ pdp_endian
49 # define byte_order _ byte_order
50 # endif
51
52 # If _ byte_order = _ little_endian
53 # DEFINE _ long_long_pair (HI, LO) Lo, hi
54 # Elif _ byte_order = _ big_endian
55 # DEFINE _ long_long_pair (HI, LO) Hi, Lo
56 # endif
57
58
59 # The macro definitions below ifdef _ use_bsd are only related to the BSD system, but not to other systems.
60/* conversion interfaces .*/
61 # include <bits/byteswap. h> // The macro defined later must use the macro of this file (for example, _ bswap_16 (x) _ bswap_32 (x)
62
63 # If _ byte_order = _ little_endian
64 # define htobe16 (x) _ bswap_16 (x) // htobe16 it means host to big-Endian 16 bits
65 # define htole16 (x) (X)
66 # define be16toh (x) _ bswap_16 (X)
67 # define le16toh (x) (X)
68
69 # define htobe32 (x) _ bswap_32 (X)
70 # define htole32 (x) (X)
71 # define be32toh (x) _ bswap_32 (X)
72 # define le32toh (x) (X)
73
74 # define htobe64 (x) _ bswap_64 (X)
75 # define htole64 (x) (X)
76 # define be64toh (x) _ bswap_64 (X)
77 # define le64toh (x) (X)
78 # else
79 # define htobe16 (x) (X)
80 # define htole16 (x) _ bswap_16 (X)
81 # define be16toh (x) (X)
82 # define le16toh (x) _ bswap_16 (X)
83
84 # define htobe32 (x) (X)
85 # define htole32 (x) _ bswap_32 (X)
86 # define be32toh (x) (X)
87 # define le32toh (x) _ bswap_32 (X)
88
89 # define htobe64 (x) (X)
90 # define htole64 (x) _ bswap_64 (X)
91 # define be64toh (x) (X)
92 # define le64toh (x) _ bswap_64 (X)
93 # endif
94 # endif
95
96 # endif/* endian. H */

//////////////////////////////////////// //////////////////////////////////////// ////
/Usr/include/byteswap. h

19 # ifndef _ byteswap_h
20 # DEFINE _ byteswap_h 1
21
22/* Get the machine specific, optimized definitions .*/
23 # include <bits/byteswap. h>
24
25
26/* the following definitions must all be macros since otherwise some
27 of the possible optimizations are not possible .*/
28
29/* return a value with all bytes in the 16 bit argument swapped .*/
30 # define bswap_16 (x) _ bswap_16 (x) // macro definition references Macros in bits/byteswap
31
32/* return a value with all bytes in the 32 bit argument swapped .*/
33 # define bswap_32 (x) _ bswap_32 (X)
34
35 # If defined _ gnuc _ & _ gnuc _> = 2
36/* return a value with all bytes in the 64 bit argument swapped .*/
37 # define bswap_64 (x) _ bswap_64 (X)
38 # endif
39
40 # endif/* byteswap. H */

//////////////////////////////////////// //////////////////////////////////////// ////
The/usr/include/bits/byteswap. h file content is as follows:

/* Macros to swap the order of bytes in integer values .*/
20
21 # If! Defined _ byteswap_h &&! Defined _ netinet_in_h &&! Defined _ endian_h
22 # error "never use <bits/byteswap. h> directly; include <byteswap. h> instead ."
23 # endif

The preceding statement indicates/usr/include/bits/byteswap. the hfile can only be contained in/usr/include/byteswap. H and usr/include/netinet/in. H and usr/include/endian. h. Note the macro definition: _ netinet_in_h indicates the in. h file in the netinet folder.

External interface header file. The preceding Conditional compilation statement format: defined macro is used to determine whether the following macro is defined. You can connect multiple conditions through.
24
25 # ifndef _ bits_byteswap_h
26 # DEFINE _ bits_byteswap_h 1
27
28/* swap bytes in 16 bit value .*/
29 # DEFINE _ bswap_constant_16 (X )/
30 (x)> 8) & 0xff) | (x) & 0xff) <8 ))

/*

The above is the specific implementation of macro _ bswap_constant_16 (x), that is, 16-bit byte exchange.

*/

31
32 # ifdef _ gnuc _ // If the compiler is GNU gcc and the version number is greater than 2
33 # If _ gnuc _> = 2
34 # DEFINE _ bswap_16 (X )/
35 (_ extension __/
36 ({register unsigned short int _ v, _ x = (x );/
37 If (_ builtin_constant_p (_ x ))/
38 _ v = _ bswap_constant_16 (_ x );/
39 else/
40__ ASM _ ("rorw $8, % W0 "/
41: "= r" (_ v )/
42: "0" (_ x )/
43: "cc ");/
44 _ v ;}))
45 # else
46/* this is better than nothing .*/
47 # DEFINE _ bswap_16 (X )/
48 (_ extension __/
49 ({register unsigned short int _ x = (x); _ bswap_constant_16 (_ x );}))
50 # endif
51 # else
52 static _ inline unsigned short int
53 _ bswap_16 (unsigned short int _ BSX)
54 {
55 return _ bswap_constant_16 (_ BSX );
56}
57 # endif
58
59/* swap bytes in 32 bit value .*/
60 # DEFINE _ bswap_constant_32 (X )/
61 (x) & 0xff000000)> 24) | (x) & 0x00ff0000)> 8) |/
62 (x) & 0x0000ff00) <8) | (x) & 0x000000ff) <24 ))
63

134 # endif
135
136 # endif/* _ bits_byteswap_h */

 

 

The above file basically implements all the macros for byte sequence conversion (note that the function is not implemented, but the function is replaced by macros ), next let's take a look at the specific/usr/include/netinet/in. h file:

/* Get system-specific definitions .*/
356 # include <bits/in. h>

357
358/* functions to convert between host and network byte order.
359
360 please note that these functions normally take 'unsigned long int' or
361 'unsigned short int' values as arguments and also return them.
362 this was a short-sighted demo-since on different systems the types
363 may have different representations but the values are always the same .*/
364
365 extern uint32_t ntohl (uint32_t _ netlong) _ Throw _ attribute _ (_ const __));
366 extern uint16_t ntohs (uint16_t _ netshort)
367 _ Throw _ attribute _ (_ const __));
368 extern uint32_t htonl (uint32_t _ hostlong)
369 _ Throw _ attribute _ (_ const __));
370 extern uint16_t htons (uint16_t _ hostshort)
371 _ Throw _ attribute _ (_ const __));
372
373 # include <endian. h>
374
375/* Get machine dependent optimized versions of byte swapping functions .*/
376 # include <bits/byteswap. h>
377
378 # ifdef _ optimize __
379/* We can optimize cballs to the conversion functions. Either nothing has
380 to be done or we are using directly the byte-swapping functions which
381 often can be inlined .*/
382 # If _ byte_order = _ big_endian
383/* The host byte order is the same as network byte order,
384 so these functions are all just identity .*/
385 # define ntohl (x) (X)
386 # define ntohs (x) (X)
387 # define htonl (x) (X)
388 # define htons (x) (X)
389 # else
390 # If _ byte_order = _ little_endian
391 # define ntohl (x) _ bswap_32 (X)
392 # define ntohs (x) _ bswap_16 (X)
393 # define htonl (x) _ bswap_32 (X)
394 # define htons (x) _ bswap_16 (X)
395 # endif
396 # endif
397 # endif

 

You can see that the host-to-network byte sequence conversion is all implemented in this file.

 

 

 

 

 

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.