次のコードを検討してください。
#include <stdio.h>
void main() {
uint32_t num = 2;
__asm__ __volatile__ ("CPUID");
__asm__ __volatile__ ("movl $1, %%ecx":);
__asm__ __volatile__ ("andl $0, %%ecx": "=r"(num));
printf("%i\n", num);
}
私の最初の期待は、このコードが出力されることでした。行0
をコメントアウトすると出力されますCPUID
が、そのままではゴミが発生していました。試行錯誤と調査の結果、ランダム レジスタの値を取得していることに気付きました。どうやらGCCは、実行されたステートメントの結果が欲しいとは想定していません。
問題は、他のレジスタで何が起こっているかに関係なく、AND の結果を適切に取得するステートメントに依存する (他の人の) コードを見たことです。私の観察によると、明らかにそのようなコードは壊れており、"=r"
を に置き換える必要があり"=c"
ます。
"=r"
私の質問は、一貫して、または明白な期待に従って動作する制約に頼ることができるでしょうか? それとも、GCC の実装があまりにも不透明/奇妙/その他であり、あらゆる状況でそれを避けるのが最善ですか?