#include <iostream>
int main()
{
char *dataptr = new char[33];
char datalocal[33];
dataptr[0] = 'a'; dataptr[1] = 0;
datalocal[0] = 'a'; datalocal[1] = 0;
printf("%p %p %c\n", dataptr, &dataptr, dataptr[0]);
printf("%p %p %c\n", datalocal, &datalocal, datalocal[0]);
delete[] dataptr;
}
出力:
0xd38050 0x7635bd709448 a
0x7635bd709450 0x7635bd709450 a
我々が見ることができるように、動的ポインタdata
本当にヒープ、0xD38050
へのポインタを含むポインタ変数(32ビット又は0x7635BD709448
で64ビット)です。
ローカル変数は、アドレス0x7635BD709450
に割り当てられた33文字の長さのバッファです。
しかし、datalocal
は、char *
値としても機能します。
私はちょっと混乱していますが、これは正式なC++の説明です。C++コードを書いている間、これは非常に自然な感じで、dataptr [0]はヒープメモリの最初の要素です(つまり、dataptrを2回デリファレンスする)が、アセンブラではポインタ変数のアドレスであるdataptr
の真の性質がわかります。したがって、ヒープポインタを最初にロードしてmov eax,[data]
= eax
を0xD38050
にロードしてから0xD38050
の内容を[eax]
を使用してXMM0にロードすることができます。
ローカル変数には変数のアドレスはありません。 datalocal
のシンボルは既に最初の要素のアドレスなので、movdqu xmm0,[data]
が動作します。
「間違っている」ケースではまだ実行できますmovdqu xmm0,[data]
; CPUが32ビットの変数から128ビットをロードすることは問題ではありません。それは単純に32ビットを超えて読み取りを続け、他の変数/コードに属する別の96ビットを読み取るだけである。メモリ境界の周りにあり、これがアプリケーションの最後のメモリページである場合、無効なアクセスでクラッシュします。
コメントは数回コメントに記載されています。それは有効なポイントです。 movdqu
を介してメモリにアクセスするには、それを整列させる必要があります。 C++コンパイラ組み込み関数をチェックしてください。 Visual Studioのために、この動作するはずです:
__declspec(align(16)) char datalocal[33];
char *dataptr = _aligned_malloc(33, 16);
_aligned_free(dataptr);
私のC++の解釈について:たぶん私は初めからこの間違ってました。
dataptr
は、dataptrシンボルの値、つまりそのヒープアドレスです。次に、dataptr[0]
はヒープアドレスを逆参照し、割り当てられたメモリの最初の要素にアクセスします。 &dataptr
は、dataptr
値のアドレスです。これは、dataptr = nullptr;
のような構文でも意味があります。ここでは、dataptrシンボルアドレスを上書きしないで、dataptr変数にnullptr値を格納します。それは配列変数だとしてdatalocal[]
で
は、基本的にdatalocal = 'a';
でのような純粋なdatalocal
にアクセスするには意味がないので、あなたは常に[]
インデックスを提供する必要があります。そして&datalocal
はそのような配列のアドレスです。純粋なdatalocal
は、char *
型を持つ配列などを使った簡単なポイント計算のためのエイリアス化されたショートカットですが、純粋なdatalocal
が構文エラーを投げるならば、C++コード(ポインタの場合は&datalocal
、要素の場合はdatalocal[..]
)、それは完全にそのdataptr
論理に適合します。
結論:アセンブリ言語で[data]
がdata
という値をロードしているので、最初から誤った例がありました。これはnew
によって返されたヒープへのポインタです。
あなたのコードに問題がdata
である。これは、私自身の説明で、現在はいくつかのC++の専門家は、ビューの正式な観点から作品にそれを来て、涙が... :)))
'data'はポインタです。 –
'[data]'の元の投稿のように、新しい/ delete with pointerの代わりにローカル変数 'char data [33];を直接使うことができますか?今はデバッグできませんが、コンパイルされたソースを想像できるので、これがうまくいくと思います。現時点で困惑していることは、 'char * data'とのC++の違いは何ですか? C++の観点からは、それらは等価であるように見えます。私はおそらく何かを見落としているでしょう。 (そしてその2番目のバージョンでは 'mov eax、data'は' mov eax、[data] 'にコンパイルされます) – Ped7g
x86には"メモリ間接 "アドレッシングモードはありません。ポインタを 'xmm0'にロードしています。 'xmm0'はポインタよりも大きいので、ポインタが格納されている場所の終わりを超えてメモリ内のガベージバイトも読み込んでいます。 –