コードvoid *p = &&abc;
に出くわしました。ここでの&&
の意味は何ですか?右辺値の参照については知っていますが、このコンテキストで使用される&&
は異なると思います。 &&
はvoid *p = &&abc;
で何を示していますか?
これはラベルのアドレスであり、 [〜#〜] gcc [〜#〜] に固有の機能です。
int main(void) {
void* startp;
s:
startp = &&s;
printf("the assignment above starts at address %p\n", startp);
return 0;
}
テストすることで、自分でそれを理解できたはずです。
int main(void) {
void* startp;
int a;
startp = &&a;
printf("startp=%p\n", startp);
return 0;
}
その場合、GCCは次のように述べています。
エラー:ラベル「a」は使用されていますが、定義されていません
これを本当に理解するにはアセンブラを知っている必要がありますが、ラベルのアドレスが何を意味するのかを説明しようと思います。
OSがディスクから.exeファイルをロードした後、「ローダー」と呼ばれるオペレーティングシステムのコンポーネント(Windowsには「PEローダー」があり、Linuxには「ELFローダー」があります。コンパイルされている場合は他のコンポーネントもあります)。カーネル)、それはそのプログラムの「仮想化」を行い、それをプロセスに変えます。
このプロセスは、それがRAMで唯一のものであり、RAM(つまり、32ビットマシンでは0x00000000-0xFFFFFFFF)全体にアクセスできる)と見なします。 。
(上記は起こっていることのほんの少しの概要です、あなたはそれを完全に理解するために本当にアセンブリを学ぶ必要があるので、私に耐えてください)
現在、ソースコードのラベルは基本的にアドレスです。 「gotolabel;」そのアドレスへのジャンプ以外は何もしません(アセンブリ内の 命令ポインタ について考えてください)。このラベルには、このRAMアドレスが格納されています。これにより、そのアドレスを見つけることができます。
ASMを学習すると、そのアドレスが実行可能ファイルの.text
セクション内の命令を指していることがわかります。 .text
セクションは、実行するプログラムの(バイナリ)コードを保持するセクションです。
これは次の方法で調べることができます。
objdump -x a.out
[〜#〜] gcc [〜#〜] で説明されているように、これを使用してジャンプテーブルを初期化できます。一部の スキャナージェネレーター のように re2c (-g
パラメーターを参照)は、これを使用してよりコンパクトなスキャナーを生成します。たぶん、同じ手法を採用している パーサジェネレータ もあります。