私はGCCのシナリオで問題を引き起こしています。私が得る行動は、私が期待する行動ではありません。要約すると、私は、ハードウェアシミュレータで実装されているx86-64用のいくつかの新しい命令を提案しています。これらの命令をテストするために、私は既存のCソースコードを取り、16進数を使って新しい命令をハンドコーディングしています。これらの命令は既存のx86-64レジスタとやりとりするので、I/O/clobberリストを使用してGCCの依存関係を宣言します。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が常に関数呼び出しのレジスタを保存して復元すると考えました。私はそれを強制することができる方法はありますか?
ありがとうございます!
EDIT:ところで、私はgccはこの呼び出し先保存のような明示的なレジスタ変数をすることはありません。この
gcc -static -m64 -mmmx -msse -msse2 -O0 test.c -o test
明快にありがとう、私はこれについて知らなかった。後続の質問として、printfの前に保存され、printfの後に復元されるカスタムレジスタセットを求める簡単な(1行の)方法がありますか? – hayesti
'unsigned long tmp = r9; printf(...); r9 = tmp; ' –