金属にライブラリ(マスクROM)が組み込まれている独自のMCUを使用しています。私が使用しているコンパイラはclangで、GCCのようなインラインASMを使用しています。私が直面している問題は、ライブラリに一貫した呼び出し規約がないため、ライブラリを呼び出すことです。解決策を見つけましたが、場合によっては、コンパイラーが呼び出しの直前にclobberが登録する最適化を行うことがわかりましたが、私が行っている方法に何か問題があると思います。これが私が使用しているコードです:
int EchoByte()
{
register int asmHex __asm__ ("R1") = Hex;
asm volatile("//Assert Input to R1 for MASKROM_EchoByte"
:
:"r"(asmHex)
:"%R1");
((volatile void (*)(void))(MASKROM_EchoByte))(); //MASKROM_EchoByte is a 16-bit integer with the memory location of the function
}
これには明らかな問題があります。変数「asmHex」がレジスタR1にアサートされている間、実際の呼び出しはそれを使用しないため、コンパイラは呼び出し時にR1が予約されていることを「認識しません」。このケースを排除するために、次のコードを使用しました。
int EchoByte()
{
register int asmHex __asm__ ("R1") = Hex;
asm volatile("//Assert Input to R1 for MASKROM_EchoByte"
:
:"r"(asmHex)
:"%R1");
((volatile void (*)(void))(MASKROM_EchoByte))();
asm volatile("//Assert Input to R1 for MASKROM_EchoByte"
:
:"r"(asmHex)
:"%R1");
}
これは私には本当に醜いようで、もっと良い方法があるはずです。また、呼び出し自体にはasmHex変数が必要であることを示さないため、コンパイラーがその間にナンセンスを実行する可能性があるのではないかと心配しています。残念ながら、((volatile void(*)(int))(MASKROM_EchoByte))(asmHex)は、引数をR2 +に入れるC規則に従うため、機能しません(R1はスクラッチ用に予約されています)
残念ながら、マスクROMライブラリを変更することは不可能であり、頻繁に使用されるルーチンが多すぎて、すべてをC /C++で再作成できないことに注意してください。
乾杯、そしてありがとう。
編集:ASMブロックで関数を呼び出すことはできますが、コンパイラには呼び出しのない関数が最適化されており、アセンブリで呼び出すと呼び出しがないように見えることに注意してください。インラインASMに関数呼び出しが含まれていることを示す方法があれば、このルートに進むことができますが、そうでない場合は、リターンアドレスが壊れる可能性があります。いずれにせよ、これを行う方法を見つけることができませんでした。