GCC で問題を引き起こすシナリオがあります。私が得る行動は、私が期待する行動ではありません。状況を要約すると、ハードウェア シミュレータに実装される x86-64 用のいくつかの新しい命令を提案しています。これらの命令をテストするために、既存の C ソース コードを使用し、16 進数を使用して新しい命令をハンドコーディングしています。これらの命令は既存の x86-64 レジスターと対話するため、入力/出力/クロバー リストを使用して GCC の依存関係を宣言します。
何が起こっているかというと、printf などの関数を呼び出すと、依存するレジスタが保存および復元されません。
例えば
register unsigned long r9 asm ("r9") = 101;
printf("foo %s\n", "bar");
asm volatile (".byte 0x00, 0x00, 0x00, 0x00" : /* no output */ : "q" (r9) );
101 は r9 に割り当てられ、インライン アセンブリ (この例では偽物) は r9 に依存しています。これはprintfがなくても正しく実行されますが、ある場合、GCCはr9を保存および復元せず、カスタム命令が呼び出されるまでに別の値がそこにあります。
おそらくGCCが変数r9への代入をこっそり変更したのではないかと思ったのですが、こうすると
asm volatile (".byte %0" : /* no output */ : "q" (r9) );
アセンブリの出力を確認すると、実際に %r9 が使用されています。
gcc 4.4.5 を使用しています。何が起こっていると思いますか?GCC は常に関数呼び出しでレジスタを保存および復元すると思っていました。強制できる方法はありますか?
ありがとう!
編集:ちなみに、私はこのようなプログラムをコンパイルしています
gcc -static -m64 -mmmx -msse -msse2 -O0 test.c -o test