2017-10-15 21 views
6

は、私はツールで生成x86_64のアーキテクチャのためのいくつかのGNUアセンブラコードを持っており、これらの命令があります。callq命令とは何ですか?

movq %rsp, %rbp 
leaq str(%rip), %rdi 
callq puts 
movl $0, %eax 

私は「callq」命令の実際のドキュメントを見つけることができません。

私はhttp://support.amd.com/TechDocs/24594.pdfを見てきましたが、これは「AMD64アーキテクチャプログラマーズ・マニュアル第3巻:汎用およびシステム命令」ですが、CALLのnear命令とfar命令しか記述していません。

私はgnuアセンブラhttps://sourceware.org/binutils/docs/as/index.htmlのドキュメントを見てきましたが、それがサポートしている指示の詳細を見つけることができませんでした。

私はその関数呼び出しを理解していますが、詳細を知りたいと思います。どこで見つけることができますか?

+0

私は不思議です@Peter、なぜあなたは答えの代わりにコメントとして回答を投稿するのですか? – prl

+1

@prl:おそらく重複していると思うときはそうしますが、私はdupターゲットを探す時間がかかりませんでした。私はこれを探します。重複していない場合は、本当の答えを書く価値があります。そして、あなたは正しい、私はちょうど答えとしてそれを掲示することができた。 –

+2

@prl:特に 'callq'に関する既存の質問はありませんでした。また、ブランチやその他のスタック命令のデフォルトオペランドサイズについては、実際には分かりません。これは初心者の質問ですが、実際には変化に答える価値があります。もし私がすべての悪い "私のコードはうまくいかず、私は何も知らない"という質問で心配しないでください。 –

答えて

7

ちょうどcallです。 Intel/AMDのマニュアルで説明を参照できるようにするには、Intel-syntax disassemblyを使用してください。

qオペランドサイズの接尾辞は技術的に適用されます(64ビットのリターンアドレスをプッシュし、RIPを64ビットのレジスタとして扱います)が、命令プリフィックスでそれを上書きする方法はありません。すなわちcalllcallwは64ビットモードではエンコードできません。そのため、一部のAT & T構文ツールではcallの代わりにcallqと表示されています。もちろんこれはretqにも当てはまります。

32ビットモードと64ビットモードでは、ツールが異なります。 (Godbolt

  • のgcc -S:常にcall/ret。ニース。
  • clang -S:callq/retqおよびcalll/retl。少なくともそれは一貫して迷惑です。
  • objdump -d:callq/retq(明示的な64ビット)とcall/ret(32ビットの暗黙的)です。 64ビットはオペランドサイズの選択肢がないので、一貫性がなく、ちょっとばかだが、32ビットはありません。 (ではないが便利選択、:。callwは16ビットにEIPを切り捨て)

    (REX.Wプレフィックスなし)一方、デフォルトのオペランドサイズが、64ビットモードで最も手順についてまだ32です。しかし、add $1, (%rdi)にはオペランドサイズの接尾辞が必要です。何も意味がない場合、アセンブラは32ビットを選択しません。たとえpushw $1とが両方とも64ビットモードでエンコード可能(and usable in practice)であっても、OTOH、pushは暗黙的にpushqです。


(上記のリンク)、Intelの命令セットREFマニュアルから:

絶対周辺コールについて、絶対オフセットは、汎用レジスタまたはメモリ位置に間接的に指定されています(r/m16、r/m32、またはr/m64)。 operand-size属性は、対象オペランド(16,32,64ビット)のサイズを指定します。64ビットモードでは、ニアコール(およびすべてのニアブランチ)のオペランドサイズが強制的に64ビットのになります。

for rel32 ...絶対オフセットと同様に、operand-size属性は、ターゲットオペランド(16,32、または64ビット)のサイズを決定します。 64ビットモードでは、オペランドサイズが近くのブランチに対して64ビットに強制されるため、ターゲットオペランドは常に64ビットになります。

は、32ビットモードでは、16ビット、または16ビット絶対アドレスを使用call r/m16にEIPを切り捨て16ビットcall rel16をコードすることができます。しかし、マニュアルによれば、オペランドサイズは64ビットモードで固定されています。

+1

私は "一貫して迷惑な"という形が好きです。

関連する問題