What is the exact meaning of :"=a"(foo) :"a"(foo), "b"(bar));
パラメータはASM命令hereに渡される方法の詳細な説明があります。つまり、bar
がebxレジスタに入り、foo
がeaxに入り、asmが実行された後、eaxにはfooの更新値が含まれます。
Error: number of operands mismatch for `mul'
ええ、それはmul
のための右の構文ではありません。おそらく、あなたはx86アセンブラリファレンスマニュアル(例えば、this)で時間を費やすべきでしょう。
また、インラインasmを使用すると、普通はbad ideaとなります。
編集:あなたの質問への回答をコメントに入力できません。
どこから始めたらいいかわかりません。これらの質問は、アセンブラがどのように動作するかを非常によく理解していないことを示しているようです。あなたのSOの答えをあなたに教えることを試みることは、実際には実用的ではありません。
しかし、私は正しい方向にあなたを指すことができます。
まず、ASMコードのこのビットを考慮してください。
movl $10, %eax
movl $15, %ebx
addl %ebx, %eax
あなたはそれが何をするのか理解していますか?これが完了したら、eaxには何が入りますか? ebxには何がありますか?さて、これでその比較:
int foo = 10, bar = 15;
__asm__ __volatile__("add %%ebx,%%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
);
を「」制約を使用することで、EAXにfoo
の値を移動するためのgccを求めています。 "b"制約を使用すると、bar
をebxに移動するよう求められます。これで、asm(つまりadd
)の命令が実行されます。 asmを終了すると、foo
の新しい値はeaxになります。それを得る?
今、mul
を見てみましょう。リンク先のドキュメントによれば、構文はmul value
であることがわかりました。それは不思議そうですね。 mul
にはどのように1つのパラメータしかありませんか?それはとの倍数ですか?
読書を続けている場合、「EAXには常に値を乗算します」と表示されます。ああ。したがって、ここでは "eax"レジスタが常に暗黙指定されています。したがって、mul %ebx
と書くと、それは実際にはmul ebx, eax
の意味になりますが、常ににはがあるので、それを書くのは実際のところありません。
しかし、それよりも少し複雑です。 ebxは32ビットの数値を保持できます。私たちはint(unsigned intsではなく)を使用しているので、ebxは2,147,483,647という大きな数値を持つことができます。しかし、あなたが2,147,483,647 * 10を掛け合わせるとどうなりますか?さて、2,147,483,647は登録簿に登録できるほど大きな数字であるため、結果は大きすぎてeaxに収まりません。したがって、乗算(常に)は2つのレジスタを使用してmul
の結果を出力します。これは、そのリンクが「EDX:EAXの結果を格納する」という言い回しを意味していました。
だから、あなたはこのようなあなたの乗算を書くことができます:
int foo = 10, bar = 15;
int upper;
__asm__ ("mul %%ebx"
:"=a"(foo), "=d"(upper)
:"a"(foo), "b"(bar)
:"cc"
);
を前と同じように、これは、乗算命令を実行し、EAX、EBXにし、FOOにバーを置きます。
asmが実行された後、eaxは結果の下位部分を含み、edxは上限を含みます。 foo * bar < 2,147,483,647の場合、fooには必要な結果が含まれ、upper
はゼロになります。さもなければ、事はより複雑になる。
しかし、それは私が喜んで行っている限りです。それ以外は、asmクラスを取る。本を読む。
PS this答えと、「追加」の例でも「間違っている」という理由を示す3つのコメントがあります。
PPSこの回答があなたの質問を解決した場合は、その隣にあるチェックマークをクリックして、カルマポイントを取得することを忘れないようにしてください。
"a"と "b"はここで何を表していますか? – Destructor
私がasmにリンクしているドキュメントを読んだ場合、引用された文字列は、asmが理解できるものにC言語変数をマップする方法を記述する「制約」であることがわかります(i386セクション[here](https:// gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html))。 "a"はeaxレジスタを指します。 「b」はebxを指します。 –
ありがとうございます。わかった。しかし、私はまだ1つの問題があります。私はfooとbar変数の値を掛けて、結果をfooに格納したい。私はあなたに与えられたリンクを訪問しましたが、これを達成するために何をすべきかを知るのは難しい時があります。 – Destructor