当前位置:网站首页>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.
边栏推荐
猜你喜欢

2022 IAA industry category development insight series report - phase II

Detailed explanation of document operation

Kotlin类与继承

spark:获取日志中每个时间段的访问量(入门级-简单实现)

Summary of feature selection: filtered, wrapped, embedded

Production environment tidb cluster capacity reduction tikv operation steps

Activity Registration: how to quickly start the open source tapdata live data platform on a zero basis?
![Rasa 3.x learning series -rasa [3.2.4] - 2022-07-21 new release](/img/1e/27f107d514ded6641410cc5a45764b.png)
Rasa 3.x learning series -rasa [3.2.4] - 2022-07-21 new release

DS binary tree - maximum distance of binary tree nodes

ISPRS2018/云检测:Cloud/shadow detection based on spectral indices for multi/hyp基于光谱指数的多/高光谱光学遥感成像仪云/影检测
随机推荐
CSDN垃圾的没有底线!
Extjs4 instance address and Chinese document address
Data analysis and mining 2
AtCoder Beginner Contest 261E // 按位思考 + dp
Which brokerage has the lowest commission? I want to open an account. Is it safe to open an account on my mobile phone
CSDN garbage has no bottom line!
Performance test - Preparation of test plan
在哪家证券公司开户最好最安全 如何开户炒股票
循环结构practice
Operation of MySQL Library
Typo in static class property declarationeslint
onBlur和onChange冲突解决方法
Leetcode · daily question · 1184. distance between bus stops · simulation
REST风格
Machine learning practice notes
Self join usage of SQL
Google Earth Engine——使用MODIS数据进行逐月数据的过火(火灾)面积并导出
Rasa 3.x 学习系列-Rasa [3.2.3] - 2022-07-18 新版本发布
Time series of machine learning
Rasa 3.x 学习系列-Rasa FallbackClassifier源码学习笔记