Compiler Optimization → C keyword volatile → memory destruction descriptor ZZ

Source: Internet
Author: User
"Memory" is special and may be the most difficult part of Embedded Assembly. To explain it clearly, first introduce the compiler optimization knowledge, and then look at the C keyword volatile. Finally, let's look at the descriptor.

1. Introduction to Compiler Optimization
The memory access speed is far less than the CPU processing speed. To improve the overall performance of the machine, hardware high-speed cache is introduced on the hardware to accelerate memory access. In addition, commands in the modern CPU are not necessarily executed in strict order. commands without relevance can be executed in disorder to make full use of the CPU command line and improve the execution speed. The above is the hardware-level optimization. Let's look at optimization at the software level: one is optimized by the programmer when writing the code, and the other is optimized by the compiler. Common Methods for Compiler optimization are: caching memory variables to registers; adjusting the command order to make full use of the CPU command line; common is re-sorting read/write commands. When optimizing regular memory, these optimizations are transparent and efficient. The solution to the problem caused by Compiler Optimization or hardware re-sorting is from the hardware (or other processors) the memory barrier (memory barrier) must be set between operations executed in a specific sequence. Linux provides a macro to solve the execution sequence problem of the compiler.
Void barrier (void)
This function notifies the compiler to insert a memory barrier, but it does not work for the hardware. The compiled code will store all the modified values in the current CPU Register into the memory, read the data from the memory again when necessary.

2. C language keyword volatile
The C language keyword volatile (note that it is used to modify the variable rather than the _ volatile _ mentioned above) indicates that the value of a variable may be changed externally, therefore, the access to these variables cannot be cached in registers and must be re-accessed each time. This keyword is often used in a multi-threaded environment, because the same variable may be modified by multiple threads when a multi-threaded program is compiled, and the program synchronizes various threads through this variable. For example:
DWORD _ stdcall threadfunc (lpvoid signal)
{
Int * intsignal = reinterpret_cast <int *> (signal );
* Intsignal = 2;
While (* intsignal! = 1)
Sleep (1000 );
Return 0;
}
Set intsignal to 2 when the thread starts, and then wait until it exits when intsignal is 1. Obviously, the intsignal value must be changed externally; otherwise, the thread will not exit. However, the thread does not exit during actual operation. Even if the value of the thread is changed to 1 in the external department, you can see the corresponding pseudo assembly code:
MoV ax, signal
Label:
If (ax! = 1)
Goto label

For the C compiler, it does not know that this value will be modified by other threads. Naturally, it is cached in the register. Remember, the C compiler has no thread concept! Volatile is required. Volatile indicates that the value may be changed outside the current thread. That is to say, we need to add the volatile keyword before intsignal in threadfunc. At this time, the compiler knows that the value of this variable will change externally, so it will read the variable again every time it is accessed, the following pseudo code shows how the loop is made:
Label:
MoV ax, signal
If (ax! = 1)
Goto label

3. Memory
With the above knowledge, it is not difficult to understand the memory modification descriptor. The memory descriptor tells GCC:
1) do not re-sort the assembly instructions embedded in this section with the preceding commands. That is, before the embedded assembly code is executed, all the preceding commands are executed.
2) Do not cache variables in registers, because this Code may use memory variables which may change in unpredictable ways, therefore, GCC inserts necessary code to first write the variable values cached in the register back to the memory. If you access these variables later, you need to re-access the memory.

If the Assembly command modifies the memory, but the GCC itself does not notice it, because there is no description in the output part. In this case, you need to add "Memory" in the description section to tell GCC that the memory has been modified, after GCC learns this information, it will insert the necessary commands before this command to write the variable values in the cache to the register back to the memory, if you want to use these variables again later, read them again.

You can also use "volatile" to achieve this goal. However, it is better to use "Memory" to add this keyword before each variable.

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.