C++逆アセンブリ学習ノート(二)
7156 ワード
Chinese:
1、アドレスポインタ参照
C++のアドレス番号は16進数で表し、変数アドレスを1つ取って&オペレータを使用し、変数だけがメモリアドレスが存在し、定数にはアドレスがない(const定義の擬似定数を含まない)
ポインタは、メモリ内の様々なデータ型のアドレスを保存するためのデータ型です.ポインタ変数はアドレスを取り出すこともできるので、マルチレベルポインタが表示されます.
C++の参照は単独で定義することはできません.定義するときは初期化する必要があります.参照は変数を表す別名であり、その任意の操作に対して、本質はその表す変数を操作することである.
2、ポインタとアドレスの違い
ポインタは変数であり、変数アドレスを保存するために使用されます.アドレスは定数で、メモリ番号です.
ポインタは変更可能で、他の変数アドレスを再保存することができます.アドレスは変更できません.
ポインタは、アドレス取得操作を実行してアドレスを得ることができる.アドレスはアドレス取得操作を実行できません.
ポインタには、保存アドレスの解釈情報が含まれる.アドレスはデータを解釈できません.
3、各種類のポインタの働き方
C++の逆アセンブリ命令で説明する
表示されるポインタタイプは、ポインタタイプに従ってアドレスデータを解釈します.コンテンツ除去操作は一般的に2つのステップに分けられ、ポインタに保存されているアドレス情報を先に取り出し、その後、このアドレスに対してコンテンツ、すなわち間接アドレスを取るプロセスであり、これもポインタを識別する重要な根拠である.
4、引用の内部動作原理を理解する
実際には参照タイプはポインタタイプですが、アドレスを格納するためのメモリ領域はユーザーにとって非表示です.
参照タイプの格納方法はポインタと同じで、メモリ領域を使用してアドレスを格納します.リファレンスはコンパイラによってのみアドレッシングされ、ポインタは手動でアドレッシングする必要があります.
参照タイプは、関数のパラメータタイプと戻りタイプとしても使用できます.参照は実際にはポインタであるため、パラメータの転送時にコピーが生成されます.
アセンブリコードから、参照タイプのパラメータもメモリ領域を占め、保存されたデータはアドレス値であることがわかります.このアドレスのデータを取り出して1を加え、+1の結果を戻します.したがって、逆アセンブリでは、このようなデータ型は参照されません.
転載先:https://www.cnblogs.com/maplewan/p/3243785.html
1、アドレスポインタ参照
C++のアドレス番号は16進数で表し、変数アドレスを1つ取って&オペレータを使用し、変数だけがメモリアドレスが存在し、定数にはアドレスがない(const定義の擬似定数を含まない)
ポインタは、メモリ内の様々なデータ型のアドレスを保存するためのデータ型です.ポインタ変数はアドレスを取り出すこともできるので、マルチレベルポインタが表示されます.
C++の参照は単独で定義することはできません.定義するときは初期化する必要があります.参照は変数を表す別名であり、その任意の操作に対して、本質はその表す変数を操作することである.
2、ポインタとアドレスの違い
ポインタは変数であり、変数アドレスを保存するために使用されます.アドレスは定数で、メモリ番号です.
ポインタは変更可能で、他の変数アドレスを再保存することができます.アドレスは変更できません.
ポインタは、アドレス取得操作を実行してアドレスを得ることができる.アドレスはアドレス取得操作を実行できません.
ポインタには、保存アドレスの解釈情報が含まれる.アドレスはデータを解釈できません.
3、各種類のポインタの働き方
C++の逆アセンブリ命令で説明する
// C++ Code:
int nVar = 0x12345678;
; 4 12345678h
mov dword ptr [ebp-10h], 12345678h
// C++ Code:
int *pnVar = &nVar;
lea ecx, [ebp-10h]
mov dword ptr [ebp-14h], ecx
// C++ Code:
char *pcVar = (char*)&nVar;
lea edx, [ebp-10h]
mov dword ptr [ebp-18h], edx
// C++ Code:
short *psnVar = (short*)&nVar;
lea eax, [ebp-10h]
mov dword ptr [ebp-1Ch], eax
// C++ Code:
printf("%08x", *pnVar);
; pnVar ecx
mov ecx, dword ptr [ebp-14h]
mov edx, dword ptr [ecx]
;printf
// C++ Code:
printf("%08x", *pcVar);
; pcVar eax
mov eax, dword ptr [ebp-18h]
; eax , 1 , ecx
movsx ecx, byte ptr [eax]
// C++ Code:
printf(“%08x", *psnVar);
; psnVar edx
mov edx, dword ptr [ebp-1Ch]
; edx , 2 , eax
movsx eax, word ptr [edx]
表示されるポインタタイプは、ポインタタイプに従ってアドレスデータを解釈します.コンテンツ除去操作は一般的に2つのステップに分けられ、ポインタに保存されているアドレス情報を先に取り出し、その後、このアドレスに対してコンテンツ、すなわち間接アドレスを取るプロセスであり、これもポインタを識別する重要な根拠である.
4、引用の内部動作原理を理解する
実際には参照タイプはポインタタイプですが、アドレスを格納するためのメモリ領域はユーザーにとって非表示です.
// C++ Code
int nVar = 0x12345678;
mov dword ptr [ebp-4], 12345678h
// C++ Code
int &nVarType = nVar;
; nVar eax
lea eax, [ebp-4]
; nVar ebp-8 , ebp-8 nVarType
; ,
mov dword ptr [ebp-8] eax;
// Add,Add int , nVar
Add(nVar);
; nVar ecx
lea ecx, [ebp-4]
; ecx , nVar
push ecx;
;
call @ILT+15 (Add) (00401014)
add esp, 4
参照タイプの格納方法はポインタと同じで、メモリ領域を使用してアドレスを格納します.リファレンスはコンパイラによってのみアドレッシングされ、ポインタは手動でアドレッシングする必要があります.
参照タイプは、関数のパラメータタイプと戻りタイプとしても使用できます.参照は実際にはポインタであるため、パラメータの転送時にコピーが生成されます.
// C++ Code
void Add(int &nVar)
{
nVar++;
}
; nVar eax
mov eax, dword ptr [ebp+8]
; eax
mov ecx, dword ptr [eax]
add ecx, 1
mov edx, dword ptr [ebp+8]
mov dword ptr [edx], ecx
ret
アセンブリコードから、参照タイプのパラメータもメモリ領域を占め、保存されたデータはアドレス値であることがわかります.このアドレスのデータを取り出して1を加え、+1の結果を戻します.したがって、逆アセンブリでは、このようなデータ型は参照されません.
転載先:https://www.cnblogs.com/maplewan/p/3243785.html