当前位置:网站首页>Use of keywords const, volatile and pointer; Assembly language and view of register status
Use of keywords const, volatile and pointer; Assembly language and view of register status
2022-07-24 15:01:00 【It's Xiaoguang a~】
keyword const、volatile Use of pointer ; Assembly language and register status check :
Let's start with an example , In order to prevent inconsistent results caused by compiler optimization, we prohibit compiler optimization here ( Actually, it has nothing to do with compiler optimization ):
Patients with a (const Inconsistent with the result caused by the use of pointers ):
#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
#pragma optimize("", off) // Prohibit the compiler from optimizing the following code
const int a = 10;
printf("%d\n",a);
int *p = (int*)&a;
*p = 100;
printf("%p\n%p\n",&a,p); // The address is the same
printf("%d,%d\n",a,*p); // Values are not the same
return 0;
#pragma optimize("", on)
}
result:
reason :
int *p = (int*)&a;
*p = 100;
The code here does correct the content of the address part , however a First defined as const Variable , So the compiler thinks a It won't change in the future , So when the program is compiled , Just put variables a The value of the beginning 10 In the register , Read directly from the register when accessing later ; Therefore, although the actual value in memory is modified when executing the above code fragment , But the value in the register is not modified , Output a When , Or read from the register , The value of the register is still 10, Therefore, the read value does not match the actual value .
Example 2 ( adopt volatile Achieve consistency of results ):
#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
volatile const int a = 10; // See if the qualifier is added volatile, If you add it, the result value is the same , On the contrary, it is different
// If the variable is added volatile modification , The contents will be reloaded from memory , Instead of copying content directly from registers .
//const int a = 10;
printf("%d\n",a);
int *p = (int*)&a;
*p = 100;
printf("%p\n%p\n",&a,p); // The address is the same
printf("%d,%d\n",a,*p); // Values are not the same
return 0;
}
Join in volatile After keyword , The system always rereads data from its memory , Even if its previous instruction just read data from there , And the read data is immediately saved . Therefore use volatile Keyword avoids inconsistency errors between reading registers and reading memory .
result:
The above two examples can also illustrate const It's not absolutely safe ,const Keywords do not guarantee that constant values are modified ( You can modify the address value directly through the pointer ).
Of course, in the above example, we can further draw a conclusion by observing the assembly code and register state during debugging , Those who have the foundation of assembly language can try it by themselves .
Patients with a ( Assembly code ):
#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
00007FF63C1C18F0 push rbp
00007FF63C1C18F2 push rdi
00007FF63C1C18F3 sub rsp,128h
00007FF63C1C18FA lea rbp,[rsp+20h]
00007FF63C1C18FF mov rdi,rsp
00007FF63C1C1902 mov ecx,4Ah
00007FF63C1C1907 mov eax,0CCCCCCCCh
00007FF63C1C190C rep stos dword ptr [rdi]
00007FF63C1C190E mov rax,qword ptr [__security_cookie (07FF63C1CC008h)]
00007FF63C1C1915 xor rax,rbp
00007FF63C1C1918 mov qword ptr [rbp+0F8h],rax
00007FF63C1C191F lea rcx,[[email protected] (07FF63C1D1026h)]
00007FF63C1C1926 call __CheckForDebuggerJustMyCode (07FF63C1C108Ch)
//volatile const int a = 10; // See if the qualifier is added volatile, If you add it, the result value is the same , On the contrary, it is different
const int a = 10;
00007FF63C1C192B mov dword ptr [a],0Ah
printf("%d\n",a);
00007FF63C1C1932 mov edx,0Ah
00007FF63C1C1937 lea rcx,[string "%d\n" (07FF63C1C9CA4h)]
00007FF63C1C193E call printf (07FF63C1C11E0h)
int *p = (int*)&a;
00007FF63C1C1943 lea rax,[a]
00007FF63C1C1947 mov qword ptr [p],rax
*p = 100;
00007FF63C1C194B mov rax,qword ptr [p]
00007FF63C1C194F mov dword ptr [rax],64h
printf("%p\n%p\n",&a,p); // The address is the same
00007FF63C1C1955 mov r8,qword ptr [p]
00007FF63C1C1959 lea rdx,[a]
00007FF63C1C195D lea rcx,[string "%p\n%p\n" (07FF63C1C9CA8h)]
00007FF63C1C1964 call printf (07FF63C1C11E0h)
printf("%d,%d\n",a,*p); // Values are not the same
00007FF63C1C1969 mov rax,qword ptr [p]
00007FF63C1C196D mov r8d,dword ptr [rax]
00007FF63C1C1970 mov edx,0Ah
00007FF63C1C1975 lea rcx,[string "%d,%d\n" (07FF63C1C9CB0h)]
00007FF63C1C197C call printf (07FF63C1C11E0h)
return 0;
00007FF63C1C1981 xor eax,eax
}
00007FF63C1C1983 mov edi,eax
00007FF63C1C1985 lea rcx,[rbp-20h]
}
00007FF63C1C1989 lea rdx,[__xt_z+1E0h (07FF63C1C9C80h)]
00007FF63C1C1990 call _RTC_CheckStackVars (07FF63C1C1343h)
00007FF63C1C1995 mov eax,edi
00007FF63C1C1997 mov rcx,qword ptr [rbp+0F8h]
00007FF63C1C199E xor rcx,rbp
00007FF63C1C19A1 call __security_check_cookie (07FF63C1C10DCh)
00007FF63C1C19A6 lea rsp,[rbp+108h]
00007FF63C1C19AD pop rdi
00007FF63C1C19AE pop rbp
00007FF63C1C19AF ret
Example 2 ( Assembly code ):
#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
00007FF7D37E18F0 push rbp
00007FF7D37E18F2 push rdi
00007FF7D37E18F3 sub rsp,128h
00007FF7D37E18FA lea rbp,[rsp+20h]
00007FF7D37E18FF mov rdi,rsp
00007FF7D37E1902 mov ecx,4Ah
00007FF7D37E1907 mov eax,0CCCCCCCCh
00007FF7D37E190C rep stos dword ptr [rdi]
00007FF7D37E190E mov rax,qword ptr [__security_cookie (07FF7D37EC008h)]
00007FF7D37E1915 xor rax,rbp
00007FF7D37E1918 mov qword ptr [rbp+0F8h],rax
00007FF7D37E191F lea rcx,[[email protected] (07FF7D37F1026h)]
00007FF7D37E1926 call __CheckForDebuggerJustMyCode (07FF7D37E108Ch)
volatile const int a = 10; // See if the qualifier is added volatile, If you add it, the result value is the same , On the contrary, it is different
00007FF7D37E192B mov dword ptr [a],0Ah
printf("%d\n",a);
00007FF7D37E1932 mov edx,dword ptr [a]
00007FF7D37E1935 lea rcx,[string "%d\n" (07FF7D37E9CA4h)]
00007FF7D37E193C call printf (07FF7D37E11E0h)
int *p = (int*)&a;
00007FF7D37E1941 lea rax,[a]
00007FF7D37E1945 mov qword ptr [p],rax
*p = 100;
00007FF7D37E1949 mov rax,qword ptr [p]
00007FF7D37E194D mov dword ptr [rax],64h
printf("%p\n%p\n",&a,p); // The address is the same
00007FF7D37E1953 mov r8,qword ptr [p]
00007FF7D37E1957 lea rdx,[a]
00007FF7D37E195B lea rcx,[string "%p\n%p\n" (07FF7D37E9CA8h)]
00007FF7D37E1962 call printf (07FF7D37E11E0h)
printf("%d,%d\n",a,*p); // Values are not the same
00007FF7D37E1967 mov rax,qword ptr [p]
00007FF7D37E196B mov r8d,dword ptr [rax]
00007FF7D37E196E mov edx,dword ptr [a]
00007FF7D37E1971 lea rcx,[string "%d,%d\n" (07FF7D37E9CB0h)]
00007FF7D37E1978 call printf (07FF7D37E11E0h)
return 0;
00007FF7D37E197D xor eax,eax
}
00007FF7D37E197F mov edi,eax
00007FF7D37E1981 lea rcx,[rbp-20h]
}
00007FF7D37E1985 lea rdx,[__xt_z+1E0h (07FF7D37E9C80h)]
00007FF7D37E198C call _RTC_CheckStackVars (07FF7D37E1343h)
00007FF7D37E1991 mov eax,edi
00007FF7D37E1993 mov rcx,qword ptr [rbp+0F8h]
00007FF7D37E199A xor rcx,rbp
00007FF7D37E199D call __security_check_cookie (07FF7D37E10DCh)
00007FF7D37E19A2 lea rsp,[rbp+108h]
00007FF7D37E19A9 pop rdi
00007FF7D37E19AA pop rbp
00007FF7D37E19AB ret
VS Debug the way assembly code is generated :
Add breakpoints first , Then debug , And then in “ debugging ”->“ window ”->“ Disassembly ”. In this way, you can see the disassembly options . If you don't add breakpoints, you can't see . Check register 、 Memory is the same .
Of course, it can also be cmd Directly output the de assembled code in the form of command line :
example ( Pay attention to the generated .s The detailed address shall be indicated in the document , use txt Open the text file format ):
C:\Users\Administrator>g++ -S C:\\Users\\Administrator\\Desktop\\testc++.cpp -o C:\\Users\\Administrator\\Desktop\\ La la la .s

Of course, we can also view the disassembly code and output results through the online compiler :
Recommend two websites ( There are actually many online compilers , Only those with distinctive features are selected here ( It's not necessarily the best , Only the right one is the best )):
C++ Shell
C++ Shell The system uses GCC 4.9.2, with Boost 1.55. It has syntax 、 Error prompt and other functions . Besides , It also supports some additional options , image C++ Standard selection (C++98/C++11/C++14)、 Warning level 、 Optimization level 、 Standard input, etc .
Although there are relatively many shortcomings , For example, lack of intelligent tips 、 create a file / project 、 Download code 、 Custom settings and other functions , And the execution speed is also slow , But the warning level 、 Optimization level function is still OK Of .
Compiler Explorer
Compiler Explorer Is an interactive compiler , Editable C/C++、Go、Swift( And more ) Code , On the right is the assembly output after compiling the code , It is more suitable for viewing assembly code . It has code highlighting 、 Custom Settings 、 Error message 、 Assembly output 、 preservation 、 Sharing and other functions .
Its disadvantage is that there is no intelligent prompt , And there are a lot of functions , Dazzling ! But the functions of checking assembly language are very OK.
边栏推荐
- The difference and relation among list, set and map
- PCA of [machine learning]
- Can't remember regular expressions? Here I have sorted out 99 common rules
- SQL Server syntax - create database
- Google Earth Engine——使用MODIS数据进行逐月数据的过火(火灾)面积并导出
- Overall testing framework for performance testing
- Can you buy 6% of financial products after opening a stock account?
- How vscode debug nodejs
- DDD based on ABP -- Entity creation and update
- Rasa 3.x 学习系列-Rasa [3.2.3] - 2022-07-18 新版本发布
猜你喜欢

Detailed explanation of IO model (easy to understand)

华为相机能力

老虎口瀑布:铜梁版小壶口瀑布

Spark: get the access volume of each time period in the log (entry level - simple implementation)

(09) flask is OK if it has hands - cookies and sessions

Strongly connected component

Bibliometrix: dig out the one worth reading from thousands of papers!

Must use destructuring props assignmenteslint

Simple encapsulation of wechat applet wx.request

REST风格
随机推荐
Time series of machine learning
AtCoder Beginner Contest 261E // 按位思考 + dp
打假Yolov7的精度,不是所有的论文都是真实可信
"After 00" is coming! Digital data ushers in a new generation of "codeless" forces
C multithreaded lock collation record
kali简洁转换语言方法(图解)
Atcoder beginer contest 261e / / bitwise thinking + DP
Which securities company is good at opening an account with flush? Excuse me, is it safe to open an account with mobile phone or stock?
Property datasource is required exception handling [idea]
Fraud detection cases and Titanic rescued cases
Spark: specify the date and output the log of the corresponding date (entry level - simple implementation)
Calculate the M-day moving average price of two stocks
PIP source switching
Detailed explanation of document operation
XOR procedure
Vector introduction and underlying principle
使用 Fiddler Hook 报错:502 Fiddler - Connection Failed
Strongly connected component
Unity uses NVIDIA flex for unity plug-in to realize the effects of making software, water, fluid, cloth, etc. learning tutorial
Performance test - Test Execution