インラインアセンブリに含まれる
-
05-07-2019 - |
質問
私たちは、クラスの割り当てとしておもちゃのオペレーティングシステムに取り組んでいます。 カーネルパニック関数の記述に問題があります。
すべてのレジスタを保存し、printfに似た関数を呼び出し、保存したレジスタを印刷してCPUを停止します。現在、マクロとして定義されています:
#define panic(...) \
do{ \
asm volatile("SAVE_REGISTERS %1\n\t" : "m="(_panic_context)); \
_panic_printk(&_panic_context, __VA_ARGS__); \
while(0)
_panic_context
は、保存されたスレッドのレジスターなどを含むグローバル変数です。問題は SAVE_REGISTERS
にあります。これは、アセンブラーヘッダーファイルのどこかで定義されたマクロですが、それをインクルードする方法がわかりません。ファイル内の単純な#includeは明らかに機能しません。私はグーグルでおもしろくて必死のものを書いてみました(アセンブラ文字列の#includeのように:-))、何も助けませんでした。これを解決する方法はありますか?
GCCを使用してMIPS用にコンパイルしています(シミュレーターで実行しています:-))
編集:
SAVE_REGISTERS
は .macro SAVE_REGISTERS
...で定義されています。他のアセンブリモジュールで使用されるため、Cマクロに含めることはできません。
パニックは可変長である必要があるため、これで.Sファイルを作成することはできません。または、少なくとも他の方法を思い付くことができませんでした。
解決
マクロの仕組みを誤解していると思います。他のコンパイルが行われる前に展開されます。 asm
を使用してマクロを含むコードを発行することはできません。マクロは展開されないためです。
代わりに、 asm
ステートメントを使用してアセンブリコードをビルドするCマクロとして SAVE_REGISTERS
を定義してみます。
#define SAVE_REGISTERS(x) \
asm volatile ("movx ax, %1", ...);
そうすれば
#define panic(...) \
do { \
SAVE_REGISTERS(_panic_context); \
_panic_printk(&_panic_context, __VA_ARGS__); \
} while(0);
他のヒント
MIPSシステムはありませんが、x86 loonixボックスで #include
を試してみて、#
がコメント文字であることを発見したので、 .include
で、ファイル名を引用するとすぐに機能しました: .include" something.i"
。
今、ヘッダーファイルとアセンブラコードの組織化されたインフラストラクチャがある場合、そもそもなぜインラインasmでこれを行うのか疑問に思う必要があります。実際の .s
または .S
ファイルを作成し、アセンブラーヘッダーファイルをインクルードし、システムのファーストクラスモジュールにするだけではどうですか?
Makefile
に既に locore.S
が含まれているプロジェクトでも、 asm を使用した小さな傑作を見てきました。 ..