14

Linux カーネル ソース コードで、次の行をtasklet_actionコードに追加しました。

printk("tasklet_action = %p\n" , *tasklet_action);
printk("tasklet_action = %p\n" , &tasklet_action);
printk("tasklet_action = %p\n" , tasklet_action);

出力で私が得る:

tasklet_action = c03441a1
tasklet_action = c03441a1
tasklet_action = c03441a1

しかし、system.mapファイル内で検索すると、tasklet_actionアドレスは にc03441a0あるため、1 バイトのオフセットがあります。

  • このオフセットがあるのはなぜですか?
  • それは常に1バイトのオフセットですか?
4

1 に答える 1

18

私の推測では、ARMをThumbモードで実行しているか、関数ポインタの下部ビットを使用して実行するモードを示す他のアーキテクチャで実行していると思います。

もしそうなら、答えはあなたの関数が実際にはsystem.mapのアドレスにあるということです。

実行時に取得する値は、場所とモードです

これらの種類のアーキテクチャでの命令は、常に2バイトまたは4バイトで整列されている必要があります。これにより、下位ビットは常にゼロのままになります。アーキテクチャが追加のモードに成長したとき、設計者はモードをエンコードするために「無駄な」ビットを利用しました。これは賢いですが、紛らわしく、あなただけのものではありません。デバッガーのような多くのソフトウェアは、これが最初に発明されたとき、多くの厄介な方法で壊れました。

この概念は、ランダムな配置で可変長の命令に慣れているx86プログラマーにとって特に混乱を招きます。

于 2013-01-02T15:55:52.427 に答える