C. What you don't know-shift

Source: Internet
Author: User

Today, we will discuss the shift issue. This operation is so simple, but how many people really understand it?

Question:

printf("0x%X\n", (0x80 << 24) >> 31);

What is the result?
If you are not sure about the final conclusion and explain it, I suggest you refer to this article.

Answer: 0 xffffffff

 

C. What you don't know-shift

[C_bg44]

Please specify the output location

 

In C, there are shifts left and right, and the difference is <and>. Our 32-bit processor, for example, shifts the binary number 0000 0000,000 0 0000,000 0 0000,000 0 0001b to the left,

It takes 0000 0000,000 0000,000 0 0000,000 0 0 0010b, and the first digit in the right half is 0 bytes. This action is equivalent to 1 <1 = 2 in the C statement, if it is 2 <1 = 4. You can see that if one digit is left, it is multiplied by 2 ,. Why? Because the permission of the binary system is 2, just like the ten-stage system, adding 0 is ten times larger than that of the binary system, the Left shift is equivalent to adding zero.

Well, there will be no problems for people with a slight foundation here,... Have you ever thought about data? -1 <1 what is the reason? The answer is-1 <1 =-2,-2 <1 =-4, which is the same as the positive number. If you ignore zookeeper in this way, you are probably not an embedded programmer. Let's look at it here.

In a computer, the number is represented by a linear number. The linear number is different from the positive number algorithm, for example,-1 = 1111 1111,111 1 1111,111 1 1111,111 1 1111b

1111 1111,111 1 1111,111 1 1111,111 1 1111b (zookeeper) <1 = 1111 1111,111 1111,111 1 1111,111 1 1 1110b (zookeeper), remember that after the migration, it's no coincidence that this operator is actually-2, and we have to admire the insights of the big picture when it was the first design! (For information about the original region, anti-market, and zookeeper, please refer to relevant materials ).

This is the first time that we have mentioned the concept of "having operators. What you need to remember is that everything is a number on a computer, you ask the computer to parse it into a keyword. It will be parsed based on the formula of the keyword number. If a variable is used for the shift operation, the computer can compute the variable type, which has the operator or the operator, so it can be shifted according to the corresponding rules, but what if it is an immediate number? -1 The number of the current computer can be seen at a glance. If the number is 100, the computer does not know whether the number is correct. So how can this problem be solved? Bit is still to be moved.

We have constructed such a number: 1000 0000,000 0 0000,000 0 0000,000 0 1B, and we do not know if there is any operator. If there is no operator, it = 0x80 00 00 01 = 2147483649; if there is a number of characters, it must be a number, because the highest bit is set to a bit, so almost it is =-111 1111,111 1 1111,111 1 1111,111 1 1111b =-0x7f FF =-2147483647, the positive number is only 2 different from the positive value of Taobao. Haha, a friend with interest can study why it is "so clever ", is it because of + 0 or-0. If you do not need to pull the cursor, start to shift.

1000 0000,000 0 0000,000 0 0000,000 0 0001b <1 = 0000 0000,000 0 0000,000 0 0000,000 0010b. So far, we found that the highest bit is cleared, so it can be interpreted as a random number or a random number = 2, no value, this is exactly the case. Why? Because the Left shift of 1 is multiplied by 2, this overflows. After the translation, it becomes an integer. We sometimes need this overflow. For example, if we take a certain digit of a number, we can leave it alone.

 

This is basically the case with the Left shift. We will change the value to the right shift of the Left shift.

I don't know if you have thought about it. The right shift of the dead will lead to such trouble. The problem is filling in a high position. For example, are the two numbers correct?

0000 0000,000 0 0000,000 0 0000,000 0 0010b> 1 =? 0000 0000,000 0 0000,000 0 0000,000 0 0001b ()

0000 0000,000 0 0000,000 0 0000,000 0 0010b> 1 =? 1000 0000,000 0 0000,000 0 0000,000 0 0001b (B)

 

1000 0000,000 0 0000,000 0 0000,000 0 0010b> 1 =? 0100 0000,000 0 0000,000 0 0000,000 0 0001b (c)

1000 0000,000 0 0000,000 0 0000,000 0 0010b> 1 =? 1100 0000,000 0 0000,000 0 0000,000 0 0001b (Ding)

It can be seen that this is a positive number and a "hidden data" shift right. No doubt, B is wrong. In this case, 0 points are used for high positions, and a is correct. We are most concerned with the second data. 1000 0000,000 0 0000,000 0 0000,000 0 0010b = 0x80 00 02, the hexadecimal number can be used to avoid the limit.
Printf ("0x % x \ n", 0x80000002> 2). The result is 0x40000001. That is to say, the value of 0 indicates that the value of 0 indicates that the value of 0 indicates that the value of C indicates that the value is correct. In this case, a and c confirm that the high position is 0 when the right shift is "under any circumstances". Is that true? Take the following example:

printf("0x%X\n", (0x80 << 24) >> 31);

According to the above rules, 0x80 = 0000 0000,000 0 0000,000 0 0000,100 0 1_ B <24 = 1000 0000,000 0 0000,000 0 0000,000 0 1_ B> 31 = 0000 0000,000 0000,000 0 0000,000 0 0001b = 0 x 01, but the result of the operation is 0 xffffffff of the Earthquake!
In this case, we need to perform a step-by-step query. Query 0x80 in rows <24 =? The result is 0x80 00 00 00, no renewal. So, say 0x80000000> 31 should be = 0xff FF, no!
Printf ("0x % x \ n", 0x80000000> 31) returns 0x1, indicating that the height is 0 bytes, it is in accordance with the principle of allow C. That's strange. 0x80 <24 = 0x80000000 and (0x80 <24)> 31! = 0x80000000> 31. Why is Shen Ma? Why is the result of the 0x80 <24 period when the result is regarded as a number of operators, so the right shift in the backend is an exception of 1 digit when the middle and high digits are used?

To answer this question, let's take a look. When the VC is opened, the parameter is sent to the primary account, as shown in the following code:

Printf ("0x % x \ n", (0x80 <24)> 31); 0046353d mov ESI, esp0046366f push 0 ffffffffh; [1] 00463541 push offset string "0x % x \ n" (4f40a4h) 00463546 call dword ptr [_ imp _ printf (516654 h)]...

We noticed that [1], the render er has directly calculated the result and cannot see the process. Let's take a look At GCC. GCC-S-O test. s test. C. The result is as follows (partial ):

Call ___ main addl $-8, % ESP pushl $-1; [2] pushl $ lc0...

[2] Here, Although GCC also calculates the result directly, it is worth noting that its method is worth noting: the same is the same number, VC 0xffffffffff confused us, But GCC clearly indicates-1, indicating that GCC considers it a positive number. This implies an immediate number (integer) of any unspecified type, which is regarded as a random number, unless you directly explain it, isn't there such a clear method in C statement:

100UL

It indicates that 100 is a random number. If you don't know the UL In the backend, the browser calls it into a random number. In fact, when we first wrote the C statement, there was such a sentence in our book, including the fact that this adult did not have a similar idea in our school.

When there is a shift to the right of the number of characters, it is used to calculate the shift to the right and fill the high with the number of characters. This can be used to explain why fill the child with 0 and fill the child with 1. In the past, the computer only regarded it as a signed number, in our two examples, one operator is 0 and the other is 1.

Backtracing VC
How is VC so evil that we cannot see a type directly using a hexadecimal number? Let's take a look at the anti-negative syntax of the following two sentences in VC:

printf("0x%X\n, 100");printf("0x%X\n, -100");

 

Printf ("0x % x \ n", 100); 0046363b mov ESI, esp0046363d push 64 h; [3] 0x64 = pushed 46363f push offset string "0x % x \ n" (4f50a4h) 00463644 call dword ptr [_ imp _ printf (517654 h)]... printf ("0x % x \ n",-100); 00463654 mov ESI, esp00463656 push 0ffffff9ch; [4] serial numbers 00463658 push offset string "0x % x \ n" (4f50a4h) 0046365d call dword ptr [_ imp _ printf (517654 h)]

After reading [3] and [4] above, we can see that no matter whether positive data is used in VC, it is just a regression, amazing success! You will be able to handle it now. So when we see a number in the internal storage or register, the first response is that this is a memory, and then we can see the unsigned memory, then calculate its "true value ". I think 99% of programmers can see a number, such as 0x00f01000. Just pick up the calculator and convert it into a ten-digit number, this may be the difference between us and maxcompute.

 

Reporter
As mentioned above, the shift right of the operator is mentioned. Of course, the shift right of the operator is involved, the shift left of the operator is involved, and the shift left of the operator is involved. Let's take a look at it here.

X86 commands

Calculate 'distinct' and move Sal to the left.
Zookeeper shifts SHL to the left
Right-shift SAR
← Right shift SHR
Shift rol and RCL in sequence

Since the operators in the C statement have <and> operators, and not all Processors may have the same round-robin commands as x86, so we will not discuss the shift. We are concerned about how to use the shift and how to use the shift.

The arithmetic shift is used for the number of operators to keep the highest bit (the highest bit) unchanged,Symbol used;

Conversely, the random shift is used for random data,Do not show the delimiter.

Use your linked credit card:

Signed int Si1 = 0x80000000; // The highest digit (character bit) = 1, so it is a digital 0046353d mov dword ptr [ebp-14h], 80000000 H printf ("0x % x \ n", Si1> 31); 00463544 mov eax, dword ptr [ebp-14h] 00463547 SAR eax, 1fh; [5] There is a number of operators, and the number is shifted to the right. Returns 0xffffffff0046354a mov ESI, esp... si1 = 0x40000000; // The highest digit (character digit) = 0, so it is a positive number of 00463562 mov dword ptr [ebp-14h], 40000000 H printf ("0x % x \ n", Si1> 30); 00463569 mov eax, dword ptr [ebp-14h] 0046356c SAR eax, 1eh; [6] There is a number of operators, and the number is shifted to the right. 0, resulting in 0x10046356f mov ESI, esp unsigned int ui2 = 0x80000000; 00463562 mov dword ptr [ebp-20h], 80000000 H printf ("0x % x \ n", ui2> 31); 00463569 mov eax, dword ptr [ebp-20h] 0046356c SHR eax, 1fh; [7] Random Number, shifted to 0046356f mov ESI, esp... unsigned int ui3 = 0x80; 00463587 mov dword ptr [ebp-2Ch], 80 h printf ("0x % x \ n", (ui3 <24)> 31 ); 0046358e mov eax, dword ptr [ebp-2Ch] 00463591 SHL eax, 18 h; [8] Random Number, please move left. The result is 0x8000000000463594 SHR eax, 1fh. [9] the value of 0 x is shifted to the right. 0x100463597 mov ESI, esp .... signed int Si4 = 0x80; 004635af mov dword ptr [ebp-38h], 80 h printf ("0x % x \ n", (Si4 <24)> 31 ); 004635b6 mov eax, dword ptr [ebp-38h] 004635b9 SHL eax, 18 h; [10] Moving far left! The value of the keyword should be shifted to the left! 004635bc SAR eax, 1fh; [11] Right Shift of data: 004635bf mov ESI, esp...

There is basically no problem with the certificate above, that is, why does the last section ([10]) shift the value of the token left?

You can think about it. In fact, the Left shift does not have a question about whether the operator bit is equal to zero. Therefore, sal = SHL. When the VC changes the value of the parameter value, the value of the parameter value is shifted to the value of the parameter value.

 

Postscript

A seemingly simple question is that many of us have been very informative since the beginning, in fact, I don't understand the nature and complexity of computing machines. A very simple question is a matter of man. In my freshman year, the micro-computer veteran said: after four years of computing, most users cannot figure out their BCD labels. Now it seems that I have to work for another four-year estimate, or most people are confused about this.

I am grateful to my colleagues from IBM and I.

 

[Please specify the output location for zookeeper]

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.