Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

A case Analysis of the relationship between bit Domain and byte order in C language

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

The knowledge points of this article "case Analysis of the relationship between C language bit Domain and byte order" are not quite understood by most people, so the editor summarizes the following content, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article, let's take a look at this "C language bit domain and byte order relationship example analysis" article.

1. problem

I wrote a protocol-related code, and the value analysis of the bit field is different from what I imagined.

problem

The head of the structure:

Parse the code and test results:

That is to say, the memory parsed by the function hexdump () is hexadecimal is 81 83 20 3B.

Parsed from the data frame

Opcode = 0x8

The fan doesn't understand why the parsed value is 0x8.

In fact, this problem is the problem of bit domain and byte order.

Test code

Don't talk too much nonsense, just write a test code

# include / / simplified structure struct iphdr {unsigned char fin:1; unsigned char rsv:3; unsigned char opcode:4; unsigned char mask:1; unsigned char payload:7; unsigned char a; unsigned char b;}; main () {struct iphdr t; unsigned char* s; / / clear memory to prevent garbled memset (& tPower0Pol 4); / / use pointer to point to structure variable t s = (unsigned char*) & t / / modify the value of memory through array access, because the value parsed by hexdump is 0x81 83, / / so 0x81 must be the lowest byte of memory data s [0] = 0x81; s [1] = 0x83; / / print out the value of the bit field member printf ("fin:%d rsv:%d opcode:%d mask:%d paylod:%d\ n", t.fincot.rsvjt. Opcode.mask.payload);}

Execution result:

Fin:1,rsv:0,opcode:8,mask:1 paylod:65

Analysis: as shown in the following figure, the purple part is the actual space layout in the memory corresponding to the bit field members. After the address increases the 0x81 assignment of the first byte from left to right, the corresponding binary of each field:

Fin:1 rsv:0 opcode:1000 mask:1 paylod:1000001

As shown in the figure above, the first byte of memory is 0x81 and the second byte is 0x83

The lowest bit [0] of the first byte 0x81 corresponds to fin,bit [3:1] corresponds to rsv,bit [7:4] corresponds to the lowest bit [0] of opcode; second byte 0x83, corresponds to mask,bit [7:1] corresponds to payload.

So the results are obvious.

2. What is the bit domain?

When some information is stored, it does not need to occupy a complete byte, but only a few or one binary bit.

For example, when storing a switch quantity, there are only two states, 0 and 1, with a binary bit. In order to save storage space and make processing easy, C language provides a data structure called "bit field" or "bit segment".

The so-called "bit field" is to divide the binary in a byte into several different regions and specify the number of bits in each region.

Each domain has a domain name, which allows you to operate by domain name in the program. In this way, several different objects can be represented by an one-byte binary bit field. 1. The definition of bit field and the description of bit field variables. The definition of bit field is similar to the definition of structure, which is in the form of:

Struct bit domain structure name {bit field list}

The list of bit fields is in the form of:

Type descriptor bit domain name: bit field length

As an example given by fans:

Struct iphdr {unsigned char fin:1; unsigned char rsv:3; unsigned char opcode:4; unsigned char mask:1; unsigned char payload:7; unsigned char a; unsigned char b;}

Bit domain variables are described in the same way as structural variables. You can define it first and then explain it, and define it at the same time or explain it directly. For example:

Struct bs {int aVO8; int BRV 2; int CRAV 6;} data

Indicates that data is a bs variable, occupying a total of two bytes. The bit field an occupies 8 bits, the bit field b occupies 2 bits, and the bit field c occupies 6 bits. There are the following points about the definition of bit field:

A bit field must be stored in the same byte and cannot span two bytes.

If there is not enough space left in one byte to store another bit field, the bit field should be stored from the next unit. You can also intentionally start a bit field from the next unit. For example:

Struct bs {unsigned aVR4 unsigned: 0 / airspace / unsigned BRV 4 / start storage from the next unit / unsigned CRAV 4}

In this bit field definition, an occupies 4 bits of the first byte, the last 4 bits fill 0 indicates no use, b starts from the second byte, occupies 4 bits, and c occupies 4 bits.

The bit field can be a bitless domain name, which is only used for filling or repositioning. Anonymous bit fields cannot be used. For example:

Struct k {int aVOR 1 int: 2 / the 2 bits cannot be used / int BRV 3 int CRAV 2}

From the above analysis, we can see that the bit field is essentially a type of structure, but its members are allocated according to binary.

This is the representation of bit field operations, that is, the addition of ": 1" means that the size of this member accounts for 1 bit of the defined type, ": 2" accounts for 2 bit, and so on. Of course, the size cannot exceed the total number of bit contained in the defined type.

A bytes (byte) is 8 bit (binary bits). For example, the type defined in your structure is u_char, a byte, a total of 8 bit, the maximum cannot exceed 8. Under 32-bit machine, short is 2 bytes, total 16bit, the maximum cannot exceed 16 32bit is 4 bytes, the maximum cannot exceed 32. And so on.

The bit field definition saves more space.

For example, in your above structure, the variable type defined is u_char, which is an one-byte type, that is, 8bit.

Fc_subtype occupies 4 bits of 8bit, which is exactly one byte.

The other eight members, each occupying 1bit, have a total 8bit, which happens to be one byte.

So if you use sizeof (struct frame_control) to calculate the size of your structure, it is 2bytes.

3. How to test whether it is currently a big end or a small end?

Computer hardware has two ways to store data: big-end byte order (big endian) and small-end byte order (little endian). Big-end byte order: the high-order byte comes first and the low-order byte comes after. This is the way humans read and write numeric values. Small-end byte order: low-order bytes first, high-order bytes last.

The big-end byte order and small-end byte order of 0x1234567 are written as follows.

Why is there a small-end byte order?

The answer is that computer circuits deal with low-order bytes first, which is more efficient, because calculations start from low-order bits. Therefore, the internal processing of the computer is a small-end byte order.

However, humans are still used to reading and writing large-end byte order. Therefore, in addition to the internal processing of the computer, almost all other occasions are large-end byte order, such as network transmission and file storage.

When a computer processes byte order, it doesn't know what are high-order bytes and what are low-order bytes. It only knows how to read the bytes in order, first the first byte, then the second byte.

If it is a large-end byte order, the high-order bytes are read first, and the low-order bytes are read later. The small-end byte order is just the opposite.

Only by understanding this can we understand how computers handle byte order.

When the processor reads external data, it must know the byte order of the data and convert it to the correct value. Then, use this value normally, regardless of byte order at all.

Even if you write data to an external device, you can write a value normally, regardless of byte order. The external device will handle the problem of byte order on its own.

Example

Still use the above example, but make the following changes

# include struct iphdr {unsigned char fin:1; unsigned char rsv:3; unsigned char opcode:4; unsigned char mask:1; unsigned char payload:7;}; main () {struct iphdr t; unsigned short * s; memset (& tMagne0Jing 2); s = (unsigned char *) & t / / Note that the 0x8183 is assigned directly, because the constant must be consistent with the host byte order, / / the small end: 83 to the low byte, / / the big end: 81 to the low byte * s = 0x8183; printf ("fin:%d rsv:%d opcode:%d mask:%d paylod:%d\ n", t.finco.opcode.opcode.mask.payload);}

Execution result:

Fin:1 rsv:1 opcode:8 mask:1 paylod:64

As you can see from the result, the value of 0x8183 received is related to the corresponding binary system:

Fin:1 rsv:001 opcode:1000 mask:1 paylod:1000000

As shown in the figure above, the first byte of memory is 0x83 and the second byte is 0x81 [different from the previous example, because we assign 0x8183 directly, and the constant is in small byte order, so the low byte is 0x83]

Visible:

Low byte 83 is given to fin+rsv+opcode

So, this shows that the ubuntu of a mouth is a small-end byte order.

4. Expand the example

Continue to modify the structure as follows to verify the layout of each member in memory when the bit field member size does not add up to an entire byte.

# include struct iphdr {unsigned char fin:1; unsigned char opcode:4; unsigned char a; unsigned char b;}; main () {struct iphdr t; unsigned char * s; memset; s = (unsigned short *) & t; t.fin = 1; t.opcode = 0xf; printf ("% x\ n", s [0]);}

Fin:1 opcode:1111

The form in memory is as follows:

If you modify the value of fin to 0:

T.fin = 0

The implementation results are as follows:

Fin:0 opcode:1111

The form in memory is as follows:

The above is the content of this article on "an example analysis of the relationship between C language bit domain and byte order". I believe we all have some understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report