変換後のコードは、特定のアクションを実行しません[重複]
Dec 18 2020
AT&T構文に基づいて特定のコードをC ++からASMに変換するタスクが与えられたので、簡単な例から始めて、最初の問題に遭遇しました。
演習を開始したコード
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
num = num << 3;
std::cout << "after: " << num << std::endl;
}
結果が得られます:
before: 1
after: 8
私の変換変数numは最初のローカル変数なので、アドレス-4(%ebp)にある必要があります
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
asm (
"mov -4(%ebp), %eax \n"
"sall $3, %eax \n"
"mov %eax, -4(%ebp) \n"
);
std::cout << "after: " << num << std::endl;
}
結果が得られます:
before: 1
after: 1
このコードがnumvarに影響を与えないのはなぜですか?
回答
2 JHBonarius Dec 18 2020 at 02:17
あなたが書いているコードは非常に実装固有です。あなたの場合、を使用ebp
する64ビットマシンで実行しているときに、32ビットアドレス指定レジスタであるを使用しているため、コードが機能しない可能性がありますrbp
。
しかし、あなたはこれに間違ってアプローチしています。純粋なアセンブリを作成するか、ローカル変数と正しくインターフェイスする正しい(拡張された)Cインラインアセンブリを使用します。それ以外の場合は、自分で経験したように、何かを変更するとすぐにコードが壊れます。
この回答によると、インラインasmは次のようになります。
asm ( "assembly code"
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
コードは次のようになります
asm (
"mov %0, %%eax;"
"sal $3, %%eax;"
"mov %%eax, %1;"
:"=r" (num)
:"r" (num)
:"%eax"
);
ただし、を指定して使用する必要はないeax
ため、コードを次のように簡略化(および明確化)することができます。
asm (
"sal $3, %[num];"
:[num] "+r" (num)
);