2017-10-31 7 views
1

以下は私のコードです。 このコードは通常のマシンではなく、アーキテクチャシミュレータ(gem5)で実行しています。ポインタを使用せずにメモリアドレスに直接アクセスする方法は?

#include <stdio.h> 
int main() 
{ 
    int *p; 
    int x; 
    p = &x; 
    p[0] = 3; 
    // *(0xffff) = 6; 
    return 0; 
} 

私が行のコメントを外すと、コンパイラーのエラーが発生します(これは間接的にポインターのオペランドが必要です)。 私は実際のマシンではなくシミュレータで実行しているので、ハードウェアの動作方法とアドレス空間を制御できます。 アドレス0xffffに値6を保存します。これを行う1つの方法は次のとおりです。

int *p; 
p = (int *)0xffff; 
p[0] = 6; 

は、私は、シミュレータ上でそれを実行していますので、これは、私のためにセグメンテーションフォールトが発生しないことに注意してください、と私は、アドレス空間を制御します。 しかし、これは非効率的な方法です。なぜなら、変数 'p'にアクセスし、0xffffを取得し、次に6を格納する必要があるからです。変数 'p'にはレジスタとして宣言されていても1サイクルかかります。ロングラン。 私は「p」は常に0xFFFFのを持っていることを知っているので、私は、コンパイラがこのコードを生成することを可能にするにはどうすればよい

*(0xffff) = 3; 

ような何かを書き込むことはできませんか? ポインタが役立ちます。

+4

あなたが言ったように、 "*すべてのポインタは助けになるでしょう*" – juanchopanza

+0

これはCの問題ではない、それはOSの問題と仮想メモリマネージャの問題です。最新のOSはリアルモードのメモリアクセスを許可していません。 (特化したハードウェア、グラフィックスなどのためにいくつかのAPIが付与されています)しかし、安全なコンピューティングの観点から見ると、この20年間の進歩は、保護モードハードウェアの代わりにAPI。あなたのシミュレータで[リアルモード](https://en.wikipedia.org/wiki/Real_mode)を設定できますか?ユーザ空間アドレス指定はどこから始まりますか? –

+1

最適化を有効にしたコンパイラは、可能であれば、 'p'変数の値を格納することを避けます。生成されたアセンブリを見て、より良い方法があることが分かっていない限り、このようなマイクロ最適化を実行すべきではありません。 – interjay

答えて

1

あなたがすべてでポインタせずにそれを行うことができるかどうかは分かりませんが、あなたは別の行にポインタを宣言したくない場合は、この操作を行うことができます:

*(int*)(0xffff) = 3; 
+0

私はすぐにシミュレータでそれを実行し、余分なサイクルを取っているかどうかを報告します。ありがとうございました。 –

0

あなたの場合余分なサイクルに関係している場合は、いくつかのインラインアセンブリを使用することができます。通常、MOV命令(MOV r/m32、imm32)を使用すると、即値をレジスタに、またはレジスタが指すアドレスに移動できます。レジスタの使用を完全にバイパスしたい場合は、C6命令(from this post)を使用することができます。

c6  04   25  0xffff  3 
    opcode modr/m  sib  address immediate 

x86アーキテクチャを使用していると仮定すると、ソースファイルのインラインアセンブリにその命令を含めることができます。

+1

適切な最適化コンパイラは自動的にジョブに最適な命令を使用します。このためにインラインアセンブリを使用する理由はありません。 – interjay

+0

証明:https:// godbolt。org/g/phUoF6 – interjay

+0

あなたは正しいです、私はそれが直接それを行うのはとても簡単だったのか分かりませんでした。 – vasia

関連する問題