Cで32ビットレジスタにアクセスすることは可能ですか?もしそうなら、どのように?そうでない場合は、アセンブリコードをCに埋め込む方法はありますか?ちなみに、私はMinGWコンパイラを使用しています。前もって感謝します!
7 に答える
レジスターのみを読み取りたい場合は、次のようにすることができます。
register int ecx asm("ecx");
明らかに、それはインスタンス化に結びついています。
別の方法は、インラインアセンブリを使用することです。例えば:
asm("movl %%ecx, %0;" : "=r" (value) : );
ecx
これにより、値が変数に格納されますvalue
。私はすでに同様の答えをここに投稿しました。
どのレジスタにアクセスしますか?
通常、汎用レジスタにはCからアクセスできません。関数でレジスタ変数を宣言できますが、使用する特定のレジスタを指定することはできません。さらに、ほとんどのコンパイラはregisterキーワードを無視し、レジスタの使用を自動的に最適化します。
組み込みシステムでは、多くの場合、ペリフェラルレジスタ(タイマー、DMAコントローラー、I / Oピンなど)にアクセスする必要があります。このようなレジスタは通常メモリマップされているため、Cからアクセスできます。
ポインタを定義することによって:
volatile unsigned int *control_register_ptr = (unsigned int*) 0x00000178;
またはプリプロセッサを使用して:
#define control_register (*(unsigned int*) 0x00000178)
または、アセンブリルーチンを使用できます。
アセンブリ言語を使用するには、(少なくとも)3つの可能性があります。
- プログラムにリンクされている別の.asmソースファイル。アセンブリルーチンは、通常の関数と同様にCから呼び出されます。これはおそらく最も一般的な方法であり、hwに依存する関数がアプリケーションコードから分離されているという利点があります。
- インラインアセンブリ
- 個々のアセンブリ言語命令を実行する組み込み関数。これには、アセンブリ言語命令が任意のC変数に直接アクセスできるという利点があります。
アセンブリをCに埋め込むことができます
http://en.wikipedia.org/wiki/Inline_assembler
ウィキペディアからの例
extern int errno;
int funcname(int arg1, int *arg2, int arg3)
{
int res;
__asm__ volatile(
"int $0x80" /* make the request to the OS */
: "=a" (res) /* return result in eax ("a") */
"+b" (arg1), /* pass arg1 in ebx ("b") */
"+c" (arg2), /* pass arg2 in ecx ("c") */
"+d" (arg3) /* pass arg3 in edx ("d") */
: "a" (128) /* pass system call number in eax ("a") */
: "memory", "cc"); /* announce to the compiler that the memory and condition codes have been modified */
/* The operating system will return a negative value on error;
* wrappers return -1 on error and set the errno global variable */
if (-125 <= res && res < 0) {
errno = -res;
res = -1;
}
return res;
}
もちろんできます。「MinGW」(gcc)は、他の回答がすでに示しているように、(他のコンパイラと同様に)インラインアセンブリを許可します。どのアセンブリかは、システムのCPUによって異なります(x86の場合は99.99%)。ただし、これにより、プログラムは他のプロセッサに移植できなくなります(何をしているのか、その理由がわかっていれば、それほど悪くはありません)。
gccのアセンブリについて説明している関連ページは、こことここにあります。必要に応じて、ここにもあります。アーキテクチャに依存するため、特定できないことを忘れないでください(gccは複数のCPU用にコンパイルできます)
直接できるとは思いません。次のようなコードを使用してインラインアセンブリを実行できます。
asm (
"movl $0, %%ebx;"
"movl $1, %%eax;"
);
32ビットプロセッサを使用していて、適切なコンパイラを使用している場合は、そうです。正確な手段は、プログラミングしている特定のシステムとコンパイラーによって異なります。もちろん、これにより、コードは可能な限り移植性が低くなります。
MinGWを使用している場合は、GCCのインラインアセンブリ構文を確認する必要があります。
通常、高水準言語で記述されたプログラムからCPUレジスタにアクセスする必要はありません。基になるマシンを抽象化し、プログラムをより多くのマシンにするために正確に発明されたC、Pascalなどの高水準言語-独立。
私はあなたが何かを実行しようとしているのではないかと思いますが、それを行うための従来の方法を使用する方法の手がかりがありません。
レジスタへのアクセスの多くは、上位レベルの構造やシステムまたはライブラリの呼び出しに隠されているため、「ダーティパート」のコーディングを回避できます。あなたがやりたいことについてもっと教えてください、そして私たちはあなたに代わりを提案するかもしれません。